简体   繁体   English

有效的JavaScript:使您的构造函数功能与新的无关

[英]Effective JavaScript: Making your Constructor Function new-agnostic

I've been reading 'Effective JavaScript' lately and I came across this question. 我最近一直在阅读“有效的JavaScript”,我遇到了这个问题。

The author explains how it's important to make your Constructor Function new-agnostic because if a developer forgets to call the Constructor with the 'new' keyword, 'this' refers to 'Window'. 作者解释了如何使构造函数与新的无关,因为如果开发人员忘记使用'new'关键字调用Constructor,'this'指的是'Window'。 That makes sense. 那讲得通。 What's confusing me is the purpose of his implementation. 令我困惑的是他实施的目的。

He advices to set up your constructor like this. 他建议像这样设置你的构造函数。

var Person = function(name, age){
  var that = this instanceof Person ? this : Object.create(Person.prototype);
  that.name = name;
  that.age = age;
  return that;
}

That makes sense. 那讲得通。 You check if 'this' is an instance of Person, meaning it was called with the 'new' keyword. 您检查'this'是否是Person的实例,这意味着它是使用'new'关键字调用的。 If it's not, create a new Object that does the same thing as 'this' and return that object. 如果不是,则创建一个与“this”相同的新Object并返回该对象。

My question is this. 我的问题是这个。 If you're setting up a new Object that does the same thing as 'this', can't we just never worry about if the constructor was called with new by foregoing 'this' and just creating the new object. 如果你正在设置一个与'this'完全相同的新Object,那么我们不能再担心是否通过前面的'this'调用了构造函数而只是创建了新对象。

var Person = function(name, age){
  var that = Object.create(Person.prototype);
  that.name = name;
  that.age = age;
  return that;
}

Why worry about 'this' and 'new' at all and why not always just create our constructors like the one above? 为什么不担心'this'和'new',为什么不总是像上面那样创建我们的构造函数?

Why worry about 'this' and 'new' at all and why not always just create our constructors like the one above? 为什么不担心'this'和'new',为什么不总是像上面那样创建我们的构造函数?

Because it is just more concise to write only 因为只写更简洁

function Person(name, age) {
    this.name = name;
    this.age = age;
}

new was invented before Object.create (which is not available in older browsers) and became the standard pattern. Object.create (旧浏览器中不可用)之前发明了new ,并成为标准模式。 Most people are so accustomed to it that they don't bother to include a if (!(this instanceof Person)) return new Person(name, age) check. 大多数人都习以为常,他们不打算包括if (!(this instanceof Person)) return new Person(name, age)检查。

If you're setting up a new Object that does the same thing as 'this', can't we just never worry about if the constructor was called with new by foregoing 'this' and just creating the new object. 如果你正在设置一个与'this'完全相同的新Object,那么我们不能再担心是否通过前面的'this'调用了构造函数而只是创建了新对象。

No, you don't always know how to create the new object. 不,您并不总是知道如何创建新对象。 this instanceof Person is also true for anything else that does inherit from Person.prototype , and does allow for class inheritance : 对于继承自Person.prototype其他任何东西, this instanceof Person也是如此,并且允许类继承

function Employee(name, age, salary) {
    Person.call(this, name, age);
    this.salary = salary;
}
Employee.prototype = Object.create(Person.prototype);

The Person.call(this) wouldn't be possible if you chose to always return a new object. 如果您选择始终返回新对象,则无法使用Person.call(this)

Yes, the effect is the same, however, it allocates one more object. 是的,效果是一样的,但是,它又分配了一个对象。 The constructor is meant to be used with new, and this technique takes car of the cases where the programmer has forgotten the new. 构造函数意味着要与new一起使用,而这种技术可以解决程序员忘记新内容的情况。

It would be better to throw an exception in the latter case if you ask me. 如果你问我,最好在后一种情况下抛出异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM