使用Object.create(),范例应该将方法附加到它们的'prototype'财产
Using Object.create(), should exemplars have methods attached to their 'prototype' property?
我一直在读我的JavaScript's "new"关键词被认为有害?以及这篇关于使用原型继承而不是"new"的Adobe文章。Adobe文章中有一个"新"示例:
function Foo() {
this.name = "foo";
}
Foo.prototype.sayHello = function() {
alert("hello from " + this.name);
};
…替换为:
var foo = {
name: "foo",
sayHello: function() {
alert("hello from " + this.name);
}
};
这里的'sayHello'方法没有附加到对象的prototype
。这是否意味着'sayHello'在内存中不必要地重复(我知道V8避免这种情况,但在旧的JS引擎中,例如),因为它被复制到从foo
继承的所有对象?
应该是:
var foo = {
name: "foo",
prototype: {
sayHello: function() {
alert("hello from " + this.name);
}
}
};
或类似的吗?
方法不附加到原型,因为这个对象成为附加到使用Object.create
新创建的对象的原型。你不需要原型的原型
请记住,Object.create
不会深度克隆对象。相反,它相当于
Object.create = function(proto) {
function F() {}
F.prototype = proto;
return new F();
}
(实际实现更复杂,但这个简短的版本说明了这个想法)
所有新创建的对象都"继承"了作为原型的foo
的方法,这里没有重复。
不,如果你使用它作为原型创建另一个对象,它不会被复制。使用Object.create
的几乎相同的代码实际上略有不同,您没有使用原型,您只是创建一个对象。要使用原型继承,请执行以下操作。请注意,使用new
仍然会设置原型链,因此您链接到的文章的标题不是非常准确,并且您仍然在单个对象上共享属性。
var foo = {
name: "foo",
sayHello: function() {
alert("hello from " + this.name);
}
};
var extended = Object.create(foo);
var extended2 = Object.create(foo);
extended.name = "first";
extended2.name = "second";
extended.sayHello(); // hello from first
extended2.sayHello(); // hello from second
// Methods are shared, outputs true
console.log(extended.sayHello === extended2.sayHello)
// Now if you delete the property again, it will go up the chain
delete extended.name;
extended.sayHello(); // hello from foo
你也可以直接写
var extended = Object.create(Foo.prototype);
如果您创建构造函数来获取新实例而不是Object.create
或new Foo
,则会重复
function createFoo() {
return {
name: "foo",
sayHello: function() {
alert("hello from " + this.name);
}
}
}
var a = createFoo();
var b = createFoo();
// The function objects are not shared
alert('Are functions the same? ' + a.sayHello === b.createFoo);
如果使用闭包方法创建对象,也不会被共享。Crockford建议创建真正的私人会员。我不使用它,因为它不使用原型链,继承很难实现,而不只是复制属性。
Function Foo() {
var name = 'foo';
this.sayHello = function () {
alert(name);
};
this.setName = function (newName) {
name = newName;
};
}
var a = new Foo();
var b = new Foo();
console.log(a.sayHello === b.sayHello); // outputs false
在这里回答我自己的问题,作为我自己的笔记,也帮助向别人解释:
。使用Object.create(),范例应该有附加到它们的
prototype
属性的方法吗?
。不,因为Object.create(parentObject)本身将parentObject设置为动态创建的构造函数的prototype
。
Also: prototype
始终是构造函数的属性,而不是普通对象的属性。如:
var someArray = [];
someArray.__proto__ === Array.prototype
object .create()动态地创建构造函数,在其第一个参数中将它们的原型设置为对象。
- 直接在函数声明上使用function.prototype.bind
- 如何迭代Array.prototype函数
- cordova:例外:财产'requestFileSystem'的[对象全局]不是函数
- Object.prototype using 'this'
- 拥有财产 - 不起作用
- 访问对象的最简单方法'的单独财产
- 在不兼容的接收器上调用的方法Set.prototype.add未定义
- 为什么可以't我用Set对象调用Array.prototype.map
- ExtJS 4 Object.prototype fail
- 如何通过Prototype或jquery移除子类的父类基类
- 复选框:使用Array.prototype.forEach调用推送选中订单,
- 财产'catch'在类型'可观察<任意>'
- 将setTimeout()包装器实现为Element.prototype中的方法
- Object.prototype.hasOwnProperty.call() vs Object.prototype.h
- 如何通过 Function.prototype.apply() 更改调用函数的参数
- Function.prototype.call和Function.protoype.all只应用一个参数
- 使用JavaScript或Prototype获取表单中的所有控件并启用它们
- JavaScript-使用B.prototype=new A()继承数组
- 选项设置文本值重复..有没有我可以检查的财产以避免重复
- 使用Object.create(),范例应该将方法附加到它们的'prototype'财产