Javascript-如何创建函数的新实例
我知道,我们可以通过以下方法创建新的函数实例。但我的问题是,还有其他方法可以达到同样的效果吗Javascript-如何创建函数的新实例,javascript,javascript-objects,Javascript,Javascript Objects,我知道,我们可以通过以下方法创建新的函数实例。但我的问题是,还有其他方法可以达到同样的效果吗 var Person = function (firstName) { this.firstName = firstName; console.log('Person instantiated'); }; var person1 = new Person('Alice'); var person2 = new Person('Bob'); // Show the firstName prop
var Person = function (firstName) {
this.firstName = firstName;
console.log('Person instantiated');
};
var person1 = new Person('Alice');
var person2 = new Person('Bob');
// Show the firstName properties of the objects
console.log('person1 is ' + person1.firstName); // logs "person1 is Alice"
console.log('person2 is ' + person2.firstName); // logs "person2 is Bob"
由于在new
声明失败的情况下,我也没有得到错误
特别是,在javascript
oops
中,概念需要不同的方法
有些时候,我甚至连new
关键字都不打,就感到困惑,一切都很好。。使用new
关键字与不使用该关键字有什么不同
例如:
var setColor = function (color) {
return color;
}
var x = setColor('red');
var y = setColor('blue');
console.log(y);
console.log(x);
调用函数时,使用new
关键字可将函数中的上下文(this
)设置为新实例化的对象,而不是window
或其他上下文,这就是为什么可以在函数中指定this.firstName
,然后将其称为person1.firstName的原因
如果不使用new
关键字,则this
的值将不会是空对象,因此您将改为分配给窗口。在这种情况下,您希望使用new
,因为您将函数用作构造函数。如果您不打算将函数用作构造函数,则不希望使用new
调用它new[function]
关键字做很多事情,但它做的主要事情是:
- 创建一个新对象
- 使用[Function]的原型作为新对象的父原型
- 执行[函数]的内容,使用
此
作为对新对象的引用
如果在没有new
的情况下调用这样一个函数,则此
引用将按照通常为函数确定的方式确定,并且通常是全局对象
要更容易发现这些错误,您可以使用严格模式:
"use strict";
var Person = function (firstName) {
this.firstName = firstName;
console.log('Person instantiated');
};
var person1 = Person('Alice');
如果执行上述代码,此
将是null
而不是全局对象,并且您将立即得到一个错误,而不是将属性分配给全局对象(并且具有难以捕获的bug)
使用new
避免此类错误的一种方法是让函数返回一个新对象,而不是构造函数:
var person = function (firstName) {
console.log('person instantiated');
return {
firstName: firstName
};
};
var person1 = person('Alice');
var person2 = person('Bob');
如果执行此操作,则无论是否使用new
,因为函数不使用this
编辑下面有一个关于原型的问题。如果您不熟悉原型,这是一项允许您指定将在对象的所有实例之间共享的属性和方法的功能:
"use strict";
var Person = function (firstName) {
this.firstName = firstName;
console.log('Person instantiated');
};
Person.prototype.getMyName = function () {
return this.firstName;
};
var person1 = new Person('Alice');
console.log(person1.getMyName());
如果执行此操作,则使用new Person()
创建的所有实例都将共享getMyName
方法
我在后面详细介绍的新的-less选项不提供此自动原型扩展,但还有其他选择:
选项1-不要使用原型:
var person = function (firstName) {
console.log('person instantiated');
return {
firstName: firstName,
getMyName: function () {
return this.firstName;
}
};
};
var person = function (firstName) {
console.log('person instantiated');
var person = Object.create(person.prototype);
person.firstName = firstName;
return person;
};
选项2-使用Object.create()
扩展原型:
var person = function (firstName) {
console.log('person instantiated');
return {
firstName: firstName,
getMyName: function () {
return this.firstName;
}
};
};
var person = function (firstName) {
console.log('person instantiated');
var person = Object.create(person.prototype);
person.firstName = firstName;
return person;
};
选项3-使用.extend()
方法将原型的内容复制到新对象:
var person = function (firstName) {
console.log('person instantiated');
return _.extend({
firstName: firstName
}, person.prototype);
};
.extend()
不是内置在JavaScript中的,但是一些库,如jQuery和lodash,提供了基本上等效的实现。我认为您需要更好地了解对象和原型在JavaScript中的工作方式
假设您有一个用例,您需要一个表示用户的对象,并存储他们的名字
不使用任何函数,只需创建具有所需属性的对象:
var person = {
first_name: 'joel'
};
这是一个标准的javascript对象——没有任何特殊之处,也没有使用new关键字来构造它。实现相同功能的另一种语法是:
var person = new Object();
person.first_name = 'joel';
再说一遍,这只是一个标准对象,没有什么特别之处
创建函数的新实例的主要原因是使用javascript的原型系统。这类似于其他语言中的类。假设您希望一个人的所有实例都有一个名为getName()
的方法。你可以确保你在每个人身上都创建了这个方法
var person = {
first_name: 'joel',
getName: function() {
return this.first_name;
}
};
或者
但是,对于这种情况,更好的方法是创建person
对象的新实例,并在person函数的prototype属性上定义getName
方法,因为您总是希望为每个用户定义此方法:
function Person() {}
Person.prototype.getName = function() {
return this.first_name;
}
var user = new Person();
user.first_name = 'joel';
console.log(user.getName());
。。。或者,根据您的示例,您可以使用Person
构造函数的参数来设置first-name属性:
function Person(first_name) {
this.first_name = first_name;
}
Person.prototype.getName = function() {
return this.first_name;
};
var user = new Person('joel');
console.log(user.getName());
请注意,使用此方法创建Person
实例时,您将始终使用new
关键字。当你考虑以下内容时,原因很明显:
function Person() {this.first_name = 'joel'; return 'test';}
console.log(window.first_name); // Undefined, as expected
console.log(Person()); // Shows "test";
console.log(window.first_name); // shows "joel".
console.log(new Person()); // Shows "{first_name: 'joel'}"
请注意,在上面的第4行中,您可以看到,如果在函数调用中省略了希望您使用的new
关键字,您就意外地修改了窗口
对象上的属性,而不是在新的常规对象上设置它
有效地-可以考虑使用<代码>新< /Cord>关键字,以使人函数的返回值被删除,而您将返回一个新的人对象实例。
还请注意,通过从函数内部省略new
关键字,检查this
是否等于window
并返回函数的新实例,可以降低意外修改window
对象的风险:
function Person() {
if (this === window) return new Person();
this.first_name = 'joel';
}
使用上述方法,您可以使用以下任一方法实例化您的person
对象,两者的效果相同:
var user1 = new Person();
var user2 = Person();
有关javascript函数和原型对象如何工作的更多信息,我建议阅读