两者之间有什么区别
var A=函数(){
this.x=函数(){
//做点什么
};
};
及
var A=function(){};
A.prototype.x=函数(){
//做点什么
};
这些例子有非常不同的结果
在查看差异之前,应注意以下几点:
- 构造函数的原型提供了一种通过实例的私有
[[prototype]]
属性在实例之间共享方法和值的方法 - 函数的此由函数的调用方式或使用绑定来设置(此处未讨论)。如果在对象上调用函数(例如
myObj.method()
),则此方法中的将引用该对象。如果调用或使用绑定未设置此,则默认为全局对象(浏览器中的窗口)或在严格模式下保持未定义状态 - JavaScript是一种面向对象的语言,即大多数值都是对象,包括函数。(字符串、数字和布尔是而不是对象。)
下面是有问题的片段:
var A=函数(){
this.x=函数(){
//做点什么
};
};
在这种情况下,变量A
被分配一个值,该值是对函数的引用。使用A()
调用该函数时,函数的this不是由调用设置的,因此它默认为全局对象,表达式this.x
有效window.x
。结果是,对右侧函数表达式的引用被指定给window.x
在下列情况下:
var A=function(){};
A.prototype.x=函数(){
//做点什么
};
发生了完全不同的事情。在第一行中,变量A
被分配一个函数的引用。在JavaScript中,默认情况下,所有函数对象都有prototype属性,因此没有单独的代码来创建a.prototype对象
在第二行中,A.prototype.x被分配一个函数的引用。如果属性不存在,这将创建一个x属性,如果不存在,则会指定一个新值。因此,与第一个示例不同的是,表达式中涉及对象的x属性
另一个例子如下。这与第一个类似(也许还有你想问的问题):
var A=新函数(){
this.x=函数(){
//做点什么
};
};
在本例中,在函数表达式之前添加了new
运算符,以便将函数作为构造函数调用。使用new
调用时,函数的this设置为引用一个新对象,该对象的私有[[Prototype]]
属性设置为引用构造函数的公共Prototype。因此,在赋值语句中,将在此新对象上创建x
属性。当作为构造函数调用时,函数默认返回其this对象,因此不需要单独的返回this语句
要检查A是否具有x属性,请执行以下操作:
console.log(A.x)//函数(){
////做点什么
// };
由于引用构造函数的唯一方法是通过A.constructor,因此new的用法并不常见。更常见的做法是:
var A=函数(){
this.x=函数(){
//做点什么
};
};
var a=新的a();
实现类似结果的另一种方法是使用立即调用的函数表达式:
变量A=(函数(){
this.x=函数(){
//做点什么
};
}());
在这种情况下,A
分配了调用右侧函数的返回值。这里再次说明,由于调用中未设置this,因此它将引用全局对象,并且this.x
有效window.x
。由于函数不返回任何内容,A
的值为undefined
如果将Javascript对象序列化到JSON或从JSON中反序列化,这两种方法之间的差异也会表现出来。序列化对象时,对象原型上定义的方法不会序列化,例如,当您只想序列化对象的数据部分,而不想序列化对象的方法时,这会很方便:
var A=function(){
this.objectsOwnProperties=“已序列化”;
};
A.prototype.prototypeProperties=“未序列化”;
var instance=newa();
console.log(instance.prototypeProperties);//“未序列化”
log(JSON.stringify(instance));
//{“objectsOwnProperties”:“正在序列化”}
相关问题:
- JavaScript是一种原型语言是什么意思?
- JavaScript中函数的作用域是什么?
- 该如何;这”;关键词工作?
旁注:这两种方法之间可能没有任何显著的内存节省,但是使用原型共享方法和属性可能比每个拥有自己副本的实例使用更少的内存
JavaScript不是低级语言。将原型或其他继承模式作为一种显式更改内存分配方式的方法,可能没有多大价值