这3个功能有什么区别?第二个函数中的new运算符有什么用?为什么要使用第一个函数而不是第三个函数?
第一
var person = function(name){
this.name = alert(name);
};
var k = new person('kkkk');
var j = new person('jjjj');
第二
var person2 = function(name){
person2.name = alert(name);
};
var k2 = new person2('kkkk2');
var j2 = new person2('jjjj2');
第三
var person3 = function(name){
person3.name = alert(name);
};
var k3 = person3('kkkk3');
var j3 = person3('jjjj3');
答案 0 :(得分:5)
alert
实际上很难检查效果,所以在我的解释中,我假设alert(name)
实际上是name
。 (alert
返回undefined
,而不是其输入)
第一个创建一个可以像类一样使用的函数。然后,您将其与new
一起使用,并创建了两个对象k
和j
。 this
设置了k.name === 'kkkk'
,以便您可以访问j.name === 'jjjj'
和k2.name
等名称。
第二个类似于第一个,但j2.name
和undefined
是person2.name
。您可以访问person2.name === 'jjjj2'
,但这只等于您上次实例化它的名称;因此,new
。
第三个类似于第二个,但不滥用k3
。 j3
和undefined
为k3.name
,如果您尝试访问j3.name
和person3
,则会收到错误消息。同样,您将能够使用person3.name
访问上次传递给{{1}}的值。
答案 1 :(得分:1)
您的第二个和第三个功能不会为person2.name
和person3.name
分配任何内容。所以从技术上讲,只有你的第一个功能才有效,这就是它应该被使用的原因。
javascript中有一个非常重要的概念叫context
。上下文可以被视为一个对象。 this
关键字是指函数执行的上下文。
您可以在this
的帮助下在当前上下文中创建新属性。例如:
var person = function(name) {
this.name = name; // this can be accessed externally, just like public properties
var _name = name; // this can be accessed only within the function, just like a private property
__name = name; // if a property is not properly initialized with a 'var' or 'this', it becomes part of 'window' object, hence you can access it from anywhere using 'window.__name'
}
您可以使用new
关键字
var k = new person2('kkkk2'); // this will create a new context, create a property name in it and assign it value passed to function.
var j = new person('jjjj'); // this will create another context
您始终可以访问不同的上下文及其属性:
alert(k.name); // this will show 'kkkk2'
alert(j.name); // this will show 'jjjj'
答案 2 :(得分:1)
第一个声明了一个函数person()
,它(可能)用作对象构造函数 - 最近的JavaScript来自于类。这意味着如果您使用new person()
调用它,JS将创建一个person
对象的新实例,并且在构造函数this
内引用该新实例,以便this.name
创建一个属性在实例上。不幸的是,您为该属性分配的值为undefined
,因为alert()
函数返回undefined
。如果你说this.name = name
它会存储函数参数中的值 - 这将是一个更正常的用法。您的k
和j
个对象都具有name
属性,并具有此语法。
第二个版本再次使用new person2()
语法,将创建person2
实例的对象,但是person2.name
会在函数本身上创建一个属性。因此,无法直接从实例k2
和j2
访问该属性,并且每次调用person2()
时,person2.name
属性都会被覆盖。在一般意义上对这样的函数具有属性没有问题,但是在这种情况下除非你真的需要记住与最近调用相关联的名称,否则它确实没有意义。
第三个版本,不使用new
关键字,只会将person3()
的返回值分配给k3
和j3
变量,但由于您没有明确地返回他们最终会以undefined
结尾的任何内容。 person3.name
的工作方式与person2
完全相同。
编辑:除此之外,请注意name
在函数的上下文中具有特殊含义,因此对于第二个和第三个选项,它的行为与创建具有其他名称的属性的行为完全不同没有特殊意义,例如myName
。