Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
998 views
in Technique[技术] by (71.8m points)

oop - Effective JavaScript: Making your Constructor Function new-agnostic

I've been reading 'Effective JavaScript' lately and I came across this question.

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'. 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. If it's not, create a new Object that does the same thing as 'this' and return that 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.

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Why worry about 'this' and 'new' at all and why not always just create our constructors like the one above?

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. 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 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.

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:

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...