ES6方法(类)在ES5中的等价物是什么?

6

我们如何在ES5中实现ES6类方法的polyfill?

我正在阅读一本书,书中写道:

class Ninja {
    constructor(name) {
        this.name = name;
    }

    swingSword() {
        return true;
    }
}

是相同的。
function Ninja(name) {
    this.name = name;
} 

Ninja.prototype.swingSword = function() {
    return true;
};

我只是想问为什么我们要在原型上添加swingSword而不是在构造函数内部添加?

因为函数应该放在对象上而不是原型链上。

我的理解是正确的吗?


2
你错了,书是对的。 - Felix Kling
书是正确的。让我们详细说明一下。 function Ninja(name) { this.name = name; } 创建一个函数对象 - Function{name: '在调用函数时传递的值'} 每次调用此函数时,都会创建并存储此函数对象以供使用。Ninja.prototype.swingSword = function() { return true; }; 而swingSword函数将位于原型上,并且在内存中只有一个引用,所有函数对象都将指向此内存地址。通过您提到的类也可以实现相同的效果。希望我的解释有所帮助。 - undefined
4个回答

2

它应该在原型上,方法不是每个实例的数据。我想不到任何一种语言以这种方式实现它,类的整个概念是拥有一整个对象类,具有相同的方法集。

如果将其放置在构造函数内部,将会为使用构造函数创建的每个实例创建一个唯一的函数。例如,1000个对象== 1000个“方法”每个对象。


谢谢你的回答。现在我明白了。 - Sourav Jaiswal
实际上,即使您在构造函数中附加函数,也不会得到每个实例1000个函数的结果。您最终会得到1000个闭包和1个函数。闭包应该是非常优化的,因此它的成本远远不及创建1000个不同的函数。此外,对于非常时间关键的方法,它们可能运行得更快(以较慢的对象创建为代价),因为Javascript引擎将首先检查this.func,然后检查Object.getPrototypeOf(this).func(等等)。但是,原型通常是最好的选择,并且需要更少的维护。 - frodeborli

1

仅将函数添加到对象中只适用于Ninja。要创建一个扩展Ninja的类,例如Kunoichi,通常会复制Ninja原型。不幸的是,由于swingSword不在原型中,您的Kunoichi无法挥舞剑。

您必须在原型中添加该函数以允许扩展该类。


0
如果我们将一个方法添加到原型中,那么在内存中只存在一个该方法的实例,并且它被所有从构造函数创建的对象共享。
如果我们直接将swingSword方法添加到Ninja构造函数中,那么每个对象都会有自己的该方法副本,占用更多的内存空间。

-5

var $class = function ($superclass, config) {
    // All classes have a superclass with the root 
    // of this $class hierarchy being Object.
    var self = function (config) {
        // Object.assign or $.extend or ...
        config && Object.assign(this, config);
    };
    self.prototype = new $superclass(config);
    return self;
};

var A = $class(Object, {
    sayWhat: "Hello, I'm an A",
    say: function () {
        console.log(this.sayWhat);
    }
});

var B = $class(A, {
    sayWhat: "Hello, I'm a B"
});

var C = $class(B, {
    say: function () {
        console.log("C SAYS: " + this.sayWhat);
    },
    superSay: function () {
        // how to call a superclass method
        B.prototype.say.call(this);
    }
});

var a = new A();
a.say();  // Hello, I'm an A

var b = new B();
b.say();  // Hello, I'm a B

var c = new C();
c.say();  // C SAYS: Hello, I'm a B

// create a "one-off" object
var d = new C({
    sayWhat: "I'm special!",
    say: function () {
        console.log("hey!");
    }
});
d.say();  // hey!
d.superSay();  // I'm special!
C.prototype.say.call(d);  // C SAYS: I'm special!


4
这段代码如何回答问题?查看 [answer] 了解如何编写有用的回答。不要只贴上一堆代码;你应该包含一些文字来解释你的代码是做什么的,以及它如何回答问题。 - Herohtar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接