有效的JavaScript:使您的构造函数成为新的不可知函数
我最近一直在读《高效JavaScript》,我遇到了这个问题 作者解释了使构造函数成为新的不可知函数的重要性,因为如果开发人员忘记使用“new”关键字调用构造函数,“this”指的是“Window”。这是有道理的。让我困惑的是他实施的目的 他建议你这样设置构造器有效的JavaScript:使您的构造函数成为新的不可知函数,javascript,oop,Javascript,Oop,我最近一直在读《高效JavaScript》,我遇到了这个问题 作者解释了使构造函数成为新的不可知函数的重要性,因为如果开发人员忘记使用“new”关键字调用构造函数,“this”指的是“Window”。这是有道理的。让我困惑的是他实施的目的 他建议你这样设置构造器 var Person = function(name, age){ var that = this instanceof Person ? this : Object.create(Person.prototype); that
var Person = function(name, age){
var that = this instanceof Person ? this : Object.create(Person.prototype);
that.name = name;
that.age = age;
return that;
}
这是有道理的。检查“this”是否是Person的实例,这意味着它是用“new”关键字调用的。如果不是,则创建一个与“this”执行相同操作的新对象,并返回该对象
我的问题是。如果您正在设置一个与“this”执行相同操作的新对象,我们就不能不担心是否通过前面的“this”和创建新对象来使用new调用构造函数
var Person = function(name, age){
var that = Object.create(Person.prototype);
that.name = name;
that.age = age;
return that;
}
为什么要担心“这个”和“新的”,为什么不总是像上面那样创建我们的构造函数呢
为什么要担心“这个”和“新的”,为什么不总是像上面那样创建我们的构造函数呢
因为只写更简洁
function Person(name, age) {
this.name = name;
this.age = age;
}
new
是在Object.create
(在旧浏览器中不可用)之前发明的,并成为标准模式。大多数人已经习惯了它,所以他们不必费心在(!(Person的这个实例))返回新的Person(姓名、年龄)检查中包含
如果您正在设置一个与“this”执行相同操作的新对象,我们就不能不担心是否通过前面的“this”和创建新对象来使用new调用构造函数
不,您并不总是知道如何创建新对象Person的此实例
也适用于从Person.prototype
继承的任何其他实例,并且允许:
如果您选择始终返回一个新对象,Person.call(this)
将不可能实现。是的,效果相同,但是,它会再分配一个对象。构造器是用来与new一起使用的,这种技术可以避免程序员忘记了new的情况
如果你问我的话,最好在后一种情况下抛出一个异常。是的,这是一种方法,尽管从技术上讲,当使用new
调用时,会创建两个对象,尽管你只使用了一个。@tylermcginis:one因为它是使用new
调用的,另一个是通过调用Object.create()
。您只是忽略了从new
@Nit创建的一个:我不想重新键入它。如果你能做得更彻底一点,我会给你+1。@dandavis:不,它仍然继承自Person.prototype
。这是同一个构造,只是使用了不同的语法。@dandavis:如果重新定义了Person
,这不会破坏继承。自然地更新到新的Person.prototype
不会反映在已经构造的对象中,但是给函数一个名称不会改变这一事实,除非您正在谈论在构造函数中为Person.prototype
添加属性,这将是非常奇怪的
如果您选择始终返回一个新对象,那么这是不可能的。“为什么会有不同?返回值被忽略,并且Person的this instanceof成功,因此that===this
。我不明白你在这里得到了什么。@CookieMonester:它适用于他的第一个三元运算符构造函数,但不适用于var that=Object.create(Person.prototype)第二个构造函数中的代码>
function Employee(name, age, salary) {
Person.call(this, name, age);
this.salary = salary;
}
Employee.prototype = Object.create(Person.prototype);