gpt4 book ai didi

JavaScript 避免使用 new 关键字

转载 作者:行者123 更新时间:2023-11-30 05:34:27 31 4
gpt4 key购买 nike

我正在阅读 this页面(特别是工厂部分)。

它提到要避免使用new 关键字,以防止不小心忘记它的情况。它建议使用工厂。

页面的新示例:

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;
}

工厂缺点:

  • 它使用更多内存,因为创建的对象不共享原型(prototype)上的方法。
  • 为了继承,工厂需要从另一个对象复制所有方法或将那个对象放在新对象的原型(prototype)上。
  • 仅仅因为遗漏 new 关键字而放弃原型(prototype)链是违背语言精神的。

避免 new 以防止在您忘记时出现问题是可以理解的。但我不太明白的是,他们说工厂示例占用更多内存,因为它没有使用原型(prototype)函数。那么为什么不使用这样的东西呢?

我的解决方案:

var Foo = function () {
var foo = function () {

};
foo.prototype = {
bar: function () { }
};
return new foo();
};

问题:我是不是漏掉了一些东西,导致这不是一个更好的解决方案?我的解决方案是否消除了列出的工厂方法的缺点,为什么或为什么不?

最佳答案

好吧,让我们以新的为例:

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();

在 google 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();
};

这不会节省内存,因为它会创建一个新的原型(prototype),以及一个新的构造函数每次您调用Foo()。所以换句话说,如果

var f1 = new Foo(), f2 = new Foo();

以下返回 false:f1.constructor == f2.constructorf1.__proto__ == f2.__proto__。这是什么意思?这意味着 f1f2 共享相同的 prototype 因此每次都必须复制对象.或许,您可以这样做:

var fooProto = {
callFoo: function() { alert("test"); }
};
function Foo() {
var foo = function() {};
foo.prototype = fooProto;
return new foo();
};

这将使用与常规构造函数相同的内存量。

侧面编辑:现代浏览器有一个内置函数,可以执行上一个示例中的 Foo 之类的操作。您可以使用 Object.create(fooProto)(但仅限于较新的浏览器)。

此外,请注意 __proto__ 在技术上是一个隐藏的只读属性(尽管某些浏览器允许您写入)。它仅用于展示幕后发生的事情,不应在实际代码中使用。

关于JavaScript 避免使用 new 关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24813533/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com