我在“JavaScript:The Good Parts”一书(第22页)中找到了以下原型构造函数(我称之为create1
)。因为作者鼓励使用new
关键字,所以我试图在没有该关键字的情况下复制此函数(create2
)。明显的缺点是它写入'protected'__proto__
属性。但是它会产生相同的结果吗?我的检查是的,但我可能是错的。为什么作者选择在这里使用new
?
Object.create1 = function(o) { var F = function(){}; F.prototype = o; return new F(); };
Object.create2 = function(o) { var n = {}; n.__proto__ = o; return n; };
var proto = { number: 15, print: function () { return "number is " + this.number; } };
var _1 = Object.create1(proto);
var _2 = Object.create2(proto);
答案 0 :(得分:3)
为什么作者选择在这里使用新的?
因为这是绝对必要的。当new
不可用时(Object.create
是非标准的),我们无法在没有.__proto__
的情况下创建原型链。
不要高估他“鼓励反对新的”。 Is JavaScript's "new" keyword considered harmful?的答案肯定是否。有些情况下纯 Object.create
更干净,而且new
经常会让新手感到困惑,但一旦你知道它是如何工作的,你就可以 - 而且应该 - 使用它。无论什么时候需要实例初始化代码,构造函数都可以完全正常。
答案 1 :(得分:1)
谈到Douglas Crockford和他对构造函数的看法,我认为你应该仔细考虑他对语法的看法。他不喜欢它,会想出很多模式来避免使用它。
在下面的演示之后,我不会过多地重视他对构造函数的看法:
http://www.youtube.com/watch?v=ya4UHuXNygM
在51:30,他说“经典继承”是错误的,因为设置Child的原型部分你必须创建一个Parent的实例。这是错的,我同意但与“经典”方式无关,因为他通过使用Object.create以“更好”的方式纠正了这种情况。他本可以以“经典”的方式使用Object.create开始,并且不需要“更好”的方式。
在1:00; 30他声称Parent构造函数代码不能在Child中重用,但我确定他知道Parent.call(this.args);
或者他知道吗?要以这种方式使用args,它确实需要您设置函数以某种方式传递和接收参数。有关此问题的详细信息,请参见“传递(构造函数)参数”
他抱怨JavaScript试图复制Java的经典继承,但后来继续抱怨在构造函数外部定义构造函数和原型的JavaScript风格看起来不太好(它看起来不像Java那样吗?)。能够在多个文件上定义对象而不必将所有内容放在一个类/函数/ 文件中是有好处的。
也许Crockford在拖钓是因为他确实曾经问过几次“你还在我身边”,而他继续摧毁JavaScript的原型部分,直到他在1:01:10结束时他想出了一个模式根本没有使用原型(尽管他赞扬JavaScript有原型,并且在此之前多次是一件很棒的事情以及之前的视频)。
我同意以下内容:http://blog.millermedeiros.com/a-case-against-private-variables-and-functions-in-javascript/
使用privates是没用的。您需要向开发人员表明他们不应该使用某些成员,然后在名称前面加下划线应该可以解决问题。如果必须的话,其他开发人员(和你)仍然可以操纵它们。这是一个冒险的事情,因为这些成员可以在任何更新中消失或重新命名,但它确实允许您测试所有内容并更容易测试(甚至Java developers complain关于私有的使用)。因此,Crockford关于在1:01:00使用该模式的论点,你认为你不具备有效点在我看来并且不喜欢语法从来都不是一个有效点,因为它没有技术价值。 / p>
在link earlier posted我试图解释构造函数和原型是如何工作的。我认为在决定它之前知道这一点很重要,并想出解决它的模式。构造函数和原型可能很难理解,甚至在人们试图告诉你不使用它时更难,而且它是错误的/过时的。很多文档都是不完整或错误的(与Crockford视频中的示例一样)我认为您应该首先理解它是什么以及如何正确使用它,因为它是JavaScript工作原理的重要部分。