JavaScript避免new关键字
JavaScript avoiding new keyword
我正在阅读这一页(特别是工厂部分)。
提到避免使用new
关键字,以防止不小心忘记它。建议使用工厂。
Page的新示例:
function Bar() {
var value = 1;
return {
method: function() {
return value;
}
}
}
Bar.prototype = {
foo: function() {}
};
new Bar();
Bar(); // These are the same.
Page的工厂示例:
function Foo() {
var obj = {};
obj.value = 'blub';
var private = 2;
obj.someMethod = function(value) {
this.value = value;
}
obj.getPrivate = function() {
return private;
}
return obj;
}
Factory Cons:
- 它使用更多的内存,因为创建的对象不共享原型的方法。
- 为了继承,工厂需要从另一个对象复制所有的方法,或者把那个对象放在新对象的原型上。
- 仅仅因为遗漏了一个新关键字就放弃原型链是违背语言精神的。
避免new
以防止万一您忘记的问题是可以理解的。但我不太明白的是,他们说工厂示例占用更多内存,因为它没有使用原型函数。所以为什么不用这样的东西呢?
我的解决方案:
var Foo = function () {
var foo = function () {
};
foo.prototype = {
bar: function () { }
};
return new foo();
};
问题:我是否错过了一些使这不是一个更好的解决方案?我的解决方案是否删除了列出的工厂方法的缺点,为什么或为什么没有?
好,让我们以new
为例:
function Bar() {
var value = 1;
// Whoops, sorry
// As Bergi points out, if you have a return value then that overrides the normal object that is returned by new
// Didn't even notice you have a return in here!
/*
return {
method: function() {
return value;
}
}
*/
// This does the same thing (approximately) but now calling "(new Bar()) instanceof Bar" will be true
this.method = function() {
return value;
};
}
Bar.prototype = {
foo: function() {}
};
var b = new Bar();
在谷歌chrome控制台,b
有一个属性称为__proto__
。基本上,当调用b.foo()
时,浏览器首先查找名为foo
的方法。如果没有找到,则在b.__proto__
和b.__proto__.__proto__
中查找,依此类推。
通知:b.__proto__ === Bar.prototype
这意味着如果您重复调用new Bar()
,它们都将具有相同的__proto__
,这节省了内存。(这有一个副作用,如果你改变了Bar.prototype
,它也会改变Bar
的__proto__
的所有实例)
让我们看看你的工厂方法:
var Foo = function () {
var foo = function () {
};
foo.prototype = {
bar: function () { }
};
return new foo();
};
这并不节省内存,因为每次调用Foo()
时,它都会创建一个新的prototype
和一个新的构造函数。换句话说,if
var f1 = new Foo(), f2 = new Foo();
以下返回false: f1.constructor == f2.constructor
和f1.__proto__ == f2.__proto__
。这是什么意思?这意味着f1
和f2
不共享相同的prototype
,因此每次都必须复制对象。也许,您可以这样做:
var fooProto = {
callFoo: function() { alert("test"); }
};
function Foo() {
var foo = function() {};
foo.prototype = fooProto;
return new foo();
};
这将使用与常规构造函数相同的内存量。
侧编辑:现代浏览器有一个内置函数,可以完成上一个示例中的Foo
。您可以使用Object.create(fooProto)
(但仅适用于较新的浏览器)。
__proto__
在技术上是一个隐藏的只读属性(尽管有些浏览器允许您写入它)。它只用于显示幕后发生的事情,不应该在实际代码中使用。
- 如何在不使用 new 关键字的情况下从函数创建对象
- “new”关键字是在构造对象时自动设置“constructor”属性的唯一方法吗
- 使用“new”关键字创建的对象和使用“Object.create”创建的对象给出不同的结果
- JavaScript:古代代码使用“new”关键字启动简单对象.为什么
- 将 JavaScript new 关键字与可变长度参数数组一起使用
- 如何判断对象是使用“Object.create”还是使用文字语法/“new”关键字创建的
- Javascript [this] 关键字绑定与 new
- 在 anthor object 中使用 Object 方法,而无需在 javascript 中使用 new 关键字
- 使用“new”关键字的Javascript函数表达式视为“静态”是否正确?
- 在javascript中使用“new”关键字的替代方案是什么?
- JavaScript 'new' 关键字,带或不带 '()'
- Javascript Module Pattern 和 new 关键字
- Javascript中“new”关键字的限制
- javascript初始化一个没有new关键字的对象
- 闭包可以使用new关键字和区别,例如,在创建新对象/类时
- 函数中的Javascript“new”关键字
- JavaScript原型继承和“new”关键字
- 向使用javascript中的new function关键字创建的函数传递参数
- 在Javascript中使用instanceof自定义对象而不使用new关键字
- 如何给一个对象's与javascript中的new关键字的属性和方法