1. 不使用new,函数正常执行,若有`return`语句,`return`的值作为返回值,若没有,在函数体执行完毕后返回`undefined`。
```
function Foo(){} //创建一个函数
var b = Foo(x, y, z); //执行这个函数并且把值赋值给b
```
2. 使用new
- 创建一个空对象,并且把this指向该对象
- 把这个对象的原型(`__proto__`)赋值为函数的【`prototype`】属性(`Foo.prototype`)
- 如果函数执行了`return`语句且返回值的类型是对象,则以该对象作为`new`调用的结果。反之,将`this`作为结果并返回。
```
var c = new Foo(x, y, z);
//下面是执行状况
function Foo(){
constructor : Foo;//隐式创建一个constructor属性,指向它构造函数。
//这里的this是不存在的,属于内部机制,我们这里用双方括号框起来只是为了方便理解。
[[this]] = {};
[[this]].__proto__ = Foo.prototype;
do something;
return result;
//在执行上面一句代码时会进行以下的判断。
if(result is Object){
return result
}else{
return [[this]];
}
}
```
顺便说一点关于`constructor`:
众所周知,通过`constructor`来判断一个对象它的构造函数,实际上这个`constructor`并不是当前对象的属性,这个值来自于这个对象的原型
```
var d = new Foo;
d.constructor //Foo
d.constructor === Foo; //true
//d本身并没有construtor属性,它会向上查找它的原型链
d.hasOwnProperty("constructor");//false
d.__proto__.hasOwnProperty("constructor");//true
d.prototype.constructor //Foo
```
### 备注:
1. `__proto__` : 原型,这个属于javascript引擎内部实现的,但是为了方便调试,v8引擎把它暴露的出来,现在浏览器大多数都实现了这个。
2. `prototype` : 每一个函数默认都会有一个`prototype`属性,该属性是一个对象,只有一个key:`constructor`,指向构造函数本身。
- 这一段比较绕,有毅力的同学可以看完:
- `prototype`属性,将作为使用`Foo`作为构造函数,`new`出来的对象的【原型】。
- 而`Foo`本身的原型是(`Function.prototype`),
- `Foo`的原型:`Foo.__proto__`,`Foo`的`prototype`属性:`Foo.prototype。`
3. `constructor` : 构造函数,可以理解成,当前对象是由哪个函数构造的,构造出来的对象并没有这个属性,这个属性在构造函数的本身,并且指向它自己,构造出来的函数是通过原型链(`__proto__`)来访问到它的。
4. `hasOwnProperty` :检测属性,这个是属于js内置的对象方法,用来检测给定的名字是否是对象的自有属性。
5. 函数的【原型】是:`Foo.__proto` 它等价于`Function.prototype`
6. 群友 王重阳:记住`function`对象才同时拥有`__proto__`和`prototype`属性,而这两个是不同的东西。而用`function`构造函数`new`的对象只有`__proto__`并且等于其构造函数的`prototype`。
感谢ECMAScript群热心网友提出的问题和修改意见。特别感谢@先知
- 不使用new,函数正常执行,若有
return语句,return的值作为返回值,若没有,在函数体执行完毕后返回undefined。
function Foo(){} //创建一个函数var b = Foo(x, y, z); //执行这个函数并且把值赋值给b
- 使用new
- 创建一个空对象,并且把this指向该对象
- 把这个对象的原型(
__proto__)赋值为函数的【prototype】属性(Foo.prototype)
- 如果函数执行了
return语句且返回值的类型是对象,则以该对象作为new调用的结果。反之,将this作为结果并返回。
var c = new Foo(x, y, z);//下面是执行状况function Foo(){ constructor : Foo;//隐式创建一个constructor属性,指向它构造函数。 //这里的this是不存在的,属于内部机制,我们这里用双方括号框起来只是为了方便理解。 [[this]] = {}; [[this]].__proto__ = Foo.prototype; do something; return result; //在执行上面一句代码时会进行以下的判断。 if(result is Object){ return result }else{ return [[this]]; }}
顺便说一点关于constructor:
众所周知,通过constructor来判断一个对象它的构造函数,实际上这个constructor并不是当前对象的属性,这个值来自于这个对象的原型
var d = new Foo;d.constructor //Food.constructor === Foo; //true//d本身并没有construtor属性,它会向上查找它的原型链d.hasOwnProperty("constructor");//falsed.__proto__.hasOwnProperty("constructor");//trued.prototype.constructor //Foo
备注:
__proto__ :
原型,这个属于javascript引擎内部实现的,但是为了方便调试,v8引擎把它暴露的出来,现在浏览器大多数都实现了这个。
prototype :
每一个函数默认都会有一个prototype属性,该属性是一个对象,只有一个key:constructor,指向构造函数本身。
- 这一段比较绕,有毅力的同学可以看完:
prototype属性,将作为使用Foo作为构造函数,new出来的对象的【原型】。
- 而
Foo本身的原型是(Function.prototype),
Foo的原型:Foo.__proto__,Foo的prototype属性:Foo.prototype。
constructor :
构造函数,可以理解成,当前对象是由哪个函数构造的,构造出来的对象并没有这个属性,这个属性在构造函数的本身,并且指向它自己,构造出来的函数是通过原型链(__proto__)来访问到它的。
hasOwnProperty :检测属性,这个是属于js内置的对象方法,用来检测给定的名字是否是对象的自有属性。
- 函数的【原型】是:
Foo.__proto 它等价于Function.prototype
- 群友
王重阳:记住
function对象才同时拥有__proto__和prototype属性,而这两个是不同的东西。而用function构造函数new的对象只有__proto__并且等于其构造函数的prototype。
感谢ECMAScript群热心网友提出的问题和修改意见。特别感谢@先知
关于使用new和不使用new,布布扣,bubuko.com
关于使用new和不使用new
原文:http://www.cnblogs.com/nunn/p/3744918.html