gpt4 book ai didi

javascript - 用JavaScript创建功能对象的优点/缺点是什么?

转载 作者:行者123 更新时间:2023-11-29 10:43:58 26 4
gpt4 key购买 nike

我只是看着道格拉斯·克罗克福德(Douglas Crockford)谈论原型(prototype)继承如何“也不是一个好主意”。

YouTube 35m55s

我真的不在乎他对JavaScript与原型(prototype)继承的看法,因为它是语言的重要组成部分,它将永远存在。

但是我想知道我通过使用链接中显示的功能对象创建而获得的好处:

// Class Free Object Oriented Programming
function constructior(init) {
var that = other_constructor(init),
member,
method = function () {
// init, member, method
};
that.method = method;
return that;
}

观看完视频后,我在他的“JavaScript The Good Parts”第5章:继承中重新阅读了有关功能对象创建的部分。

但是我看不到 有很大的区别。
我可以使用构造函数模式来获得私有(private)成员:
function Constructor (value) {
var private = value;
this.getPrivate = function () {
return private;
}
}
var OBJ1 = new Constructor(5);
var OBJ2 = new Constructor('bacon');

console.log( OBJ1.getPrivate() ); // 5
console.log( OBJ2.getPrivate() ); // bacon

我可以在构造函数模式和功能模式之间发现的 唯一差异是 new关键字的省略。通过避免使用 new关键字,我们可以避免忘记 new关键字的错误。

写这个:
var panda = createBear();

代替这个:
var panda = new Bear();

让我认为这主要取决于个人喜好。我可以看到避免使用 new关键字会很有用,我可以采用功能模式。
但这是我能看到的唯一理由。我能不能得到更多的信息,为什么一个会比另一个更好或更坏?

最佳答案

好了,我将在这里尝试用我收到的信息以及提出问题后在互联网上收集到的其他信息回答我自己的问题。

TL; DR:

它们都是有用的,并且可以实现大多数相同的事情。构造函数可以访问其原型(prototype),这非常有用,因为这意味着它们在使用构造函数创建的所有实例中都具有“全局”值。它既有用又有潜在危险。之所以有用,是因为构造函数的所有实例都可以访问相同的原型(prototype)属性,从而避免了重复。危险,因为您可以覆盖构造函数属性,为该实例提供相同名称的属性-使其更难访问原型(prototype)值。

调用Constructor时有忘记new关键字的危险,但是可以通过在Constructor函数内部添加"use strict";来轻松解决,如果您忘记new关键字,则会引发错误。

如果要避免原型(prototype)及其功能/危险,可以使用工厂
功能。
“功能性”方法真正有用的功能是可以返回任何您喜欢的东西。而不是总是构造预定义对象的“子代”。

我从这一切中学到的是,当您同时使用两者时,选择一个来另一个是愚蠢的。他们都有自己的长处和短处,人们需要记住道格拉斯·克罗克福德只是一个人,而不是JavaScript的上帝。 (那是Brandon Eich,大声笑!)

@Domenic在What difference is there in JavaScript between a constructor function, and function returning object which is invoked as a constructor?上接受的答案
让我对两种对象创建方法之间的异同有一些见解。

build 者

使用new关键字在新对象与其派生的构造函数对象之间创建链接。构造函数是新对象的原型(prototype),而新对象是原型(prototype)对象的实例。

var Constructor = function () {
this.x = 0;
this.y = 0;
};
var A = new Constructor();
console.log(A instanceof Constructor ); // true

链接到原型(prototype)对象意味着我们的新对象可以访问原型(prototype)属性,而不必将其存储在对象本身内。与在每个子对象上创建属性相比,这不仅提高了内存效率,而且还带来了原型(prototype)开发功能的额外好处。

向对象原型(prototype)添加属性或方法很简单:
Constructor.prototype.color = 'yellow';

现在,使用Constructor对象创建的每个对象都可以访问 .color属性,而无需将其存储在内部。
var A = new Constructor();
console.log(A.color); // yellow
console.log(A.hasOwnProperty('color')); // false

由于JavaScript中的对象是动态的,这意味着您可以“追溯”向原型(prototype)添加新属性,并且在更改之前创建的对象仍将“继承”新属性。
var A = new Constructor();
Constructor.prototype.food = 'bacon';
console.log(A.food); // bacon;

Crockford可能会提倡反对Constructor模式的原因之一是要避免覆盖原型(prototype)属性或意外覆盖子对象内部原型(prototype)的 namespace 。
Constructor.prototype.number = 5;
A.calculate = function () {
return A.number * 5;
}
console.log(A.calculate()); // 25

Constructor.prototype.number = 'fishsticks';
console.log(A.calculate()); // NaN

据我了解,创建后添加属性也会使代码在V8引擎中的运行速度变慢,因为对象不再共享相同的“隐藏类”,但是我对此并不了解。 Breaking the JavaScript Speed Limit with V8

仍然可以访问原型(prototype)。通过现在不建议使用的 .__proto__.或新的 Object.getPrototypeOf()方法。
console.log(Object.getPrototypeOf(A.color)); // yellow

Crockford提倡不使用构造函数的另一个原因是,您可能忘记键入 new。如果您忘记在构造函数的前面编写 new,它将运行构造函数而不是创建新对象。
var A = Constructor();
console.log(A); // undefined

通过在函数中添加严格类型可以轻松解决此问题,如果您忘记了 new关键字,则会抛出错误。
var Constructor = function () {
"use strict";
this.x = 0;
this.y = 0;
}
var A = Constructor();

console.log(A);
// Uncaught TypeError: Cannot set property 'x' of undefined

工厂功能

我发现这很简单。如果不想处理 new关键字以及Constructor函数的某些“危险”,则可以使用这种方法创建不使用其原型(prototype)的对象。
function factory () {
var obj = {
x: 0,
y: 0
}
return obj;
}
var A = factory(); // {x: 0, y: 0}

当您要处理数据而不只是创建对象时,这可能非常方便。
function factory () {
if ( new Date().getHours() < 8 ) {
return "can't create object. Need Coffe!"
};
var obj = {
x: 0,
y: 0
}
return obj;
}
var A = factory(); // Before 8 am: "can't create object. Need Coffe!"
var A = factory(); // After 8 am: {x: 0, y: 0};

这样做会失去原型(prototype)的功能/危险。因为对象没有绑定(bind)到一个。
factory.prototype.foo = "bar";
A = factory();
console.log(A.foo); // undefined

这意味着您不能使用它。但这也意味着您无法搞砸。

结论。

请参见 TL; DR

我在搜索和编写本文方面学到了很多东西,希望其他人也能学到一两个东西。

引用:

What difference is there in JavaScript between a constructor function, and function returning object which is invoked as a constructor?

Constructor function vs Factory functions

It’s time to start using JavaScript strict mode

关于javascript - 用JavaScript创建功能对象的优点/缺点是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23158732/

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