学习内容摘自 阮一峰博客
目录
- 对象的概念
- 构造函数
- new 命令
3.1基本用法
3.2new命令的原理
对象的概念
对象是单个实物的抽象;
对象是一个容器,封装了属性property和方法methd
构造函数
典型的面向对象编程语言c++/java存在类的概念,所谓类就是对象的模板,对象就是类的实例.但是javascript语言的对象体系,不是基于类的,而是基于构造函数constructor和原型链prototype.
javascript语言使用构造函数constructor作为对象的模板.所谓的构造函数,就是专门用来生成对象的函数,他提供模板,描述对象的基本结构.一个构造函数可以生成多个对象,这些对象都有相同的结构.
var Vehicle = function(){
this.price = 1000;
};
上面代码中,Vechicle就是构造函数,他提供模板,用来生成对象实例,为了与普通函数的区别,构造函数名字的第一个字母通常大写.
构造函数的两个特点:
- 函数体内使用this关键字,代表了所有生成对象的实例;
- 生成对象的时候们必须用new命令,调用Vehicle函数
new命令
基本用法
//new命令的作用,就是执行构造函数,返回一个实例对象
var Haha = function(){
this.price = 1000;
};
var v = new Haha();
v.price;
/*
分析:通过new命令,让构造函数Haha生成一个实例对象,保存在变量v中,这个新生成的实例对象,从构造函数Haha继承了price属性,在new命令执行时,构造函数内部的this,就代表了新生成的实例对象,this.price表示的实例对象有一个price属性,他的值是1000
*/
---
---
//使用new命令时,根据需要,构造函数也可以接受参数.
var Haha = function(p){
this.price = p;
};
var v = new Haha(1000);
v.price;
---
---
new 命令本身就可以执行构造函数,所以后的构造函数可以带括号,也可以不带括号.下面两行代码是等价的
var v = new Haha();
var v = new Haha;
如果忘记写new命令,直接调用构造函数会发生什么事?
这种情况下,构造函数就变成普通函数,并不会生成实例对象,而且this此时代表全局对象,将造成一些意向不到的结果
var Haha = function(){
this.price = 1000;
};
console.log(v.price);
//报错,Cannot read property 'price' of undefined
console.log(price);//1000
# 上面代码中,调用Haha构造函数时忘了加new命令,结果price属性变成了全局变量,而变量v变成了undefined.
因此,应该非常小心,避免出现不使用new命令,直接调用构造函数的情况,为了保证构造函数必须与new命令一起使用,一个解决办法是,在构造函数内部使用严格迷失,即第一行加上use strict
function Food(water,apple){
this._water = water;
this._app = apple;
}
Food();
//typeerror;cannot set property _water of undefined
---
---
另一种解决办法,是在构造函数内部判断是否使用new命令,如果发现没有使用,则直接返回一个实例对象.
function Fubar(foo,bar){
if(!(this instanceof Fubar)){
return new Fubar(foo,bar);
}
this._foo = foo;
this._bar = bar;
}
console.log(Fubar(1,2)_foo)//1
console.log((new Fubar(1,2))._foo);//1
上面代码中的构造函数,不管加不加new命令,都会得到同样的结果
new命令的原理
使用new命令时,它后面的函数调用就不是正常的调用,而是依次执行下面的步骤.
- 创建一个空对象,作为将要返回的对象实例
- 将这个空对象的原型,指向构造函数的prototype属性
- 将这个空对象赋值给函数内部的this关键字,
- 开始执行构造函数内部的代码
也就是构造函数内部,this指的是一个新生成的空对象,所有针对this的操作都会发生在这个空对象上.构造函数之所以叫构造函数,就是说这个函数的目的,就是操作一个空对象,即this,将其构造为需要的样子.
如果构造函数内部有return语句,而且return后面跟着一个对象,new命令会返回return语句指定的对象,否则,就会不管return语句,返回this对象
var Haha = function(){
this.price = 1000;
return 1000;
};
(new Haha())===1000;
//false
---
---
但是,如果return语句返回的是一个跟this无关的新对象,new命令会返回这个新对象,而不是this对象,这一点需要特别引起注意
var Haha = function(){
this.price = 100;
return {price:200};
};
(new Haha()).price
//200
另一方面,如果对普通函数(内部没有this关键字的函数)使用new命令,则返回一个空对象
function getMessage(){
return 'this is a message';
}
var msg = new getMessage();
console.log(msg);//{}
typeof msg; //"Object"
上面代码中,getMessage是一个普通函数,返回一个空字符串,对他使用new命令,会得到一个空对象,这是因为new命令总是返回一个对象,要么是实例对象,要么是reutrn语句指定的对象,本例中,return语句返回的是字符串,所以new命令就忽略了该语句.