标签:虚线 技巧 方法 images 构造函数 style 参数 console 使用
创建自定义对象的最简单方法就是创建一个Object的实例,再为他添加属性和方法。
1 var people = new Object(); 2 people.name = "yewenxiang"; 3 people.age = 24; 4 people.sayName = function(){ 5 console.log(this.name); 6 }
还可以使用对象字面量语法创建一个对象,等价于上面的代码
1 var people = { 2 name:"yewenxiang", 3 age:24, 4 sayName:function(){ 5 console.log(this.name); 6 } 7 }
这个方法是new Object() 来创建一个people对象的实例,有一个很大的问题:
为了解决上面问题发明了用函数来创建一个对象的方法:
1 function People(name,age){ 2 var o = new Object(); 3 o.name = name; 4 o.age = age; 5 o.sayName = function(){ 6 console.log(this.name); 7 } 8 return o; 9 } 10 var people1 = People("yewenxiang",24); 11 console.log(people1.name); 12 people1.sayName();
函数People()能接收两个参数,可以无限次的调用这个函数,每次都会返回一个对象,对象的基本属性为传入函数的参数,解决了创建多个相似对象导致代码臃肿的问题。但是不能识别创建的对象类型,创建的对象的构造函数全部是Object。
console.log(people1 instanceof Object); //true
构造函数模式可以用来创建自定义类型的对象,原生的构造函数类型有Object Array String等等。
1 function People(name,age){ 2 this.name = name; 3 this.age = age; 4 this.sayName = function(){ 5 console.log(this.name); 6 } 7 } 8 var people1 = new People("yewenxiang",24); 9 var people2 = new People("xiangwang",23); 10 console.log(people1.name); 11 console.log(people1 instanceof People); //true 12 console.log(people1 instanceof Object); //true
这个例子中创建的对象实例既是Object对象的实例,也是自定义构造函数People 的实例。
构造函数缺点:
上面的构造函数可以这么定义
1 function People(name,age){ 2 this.name = name; 3 this.age = age; 4 this.sayName = new Function(){ 5 console.log(this.name); 6 } 7 }
看第四行代码。每次实例化一个对象,sayName属性都指向了一个不同的函数引用,也就是指向了由Function构造函数创建的不同实例。
1 function People(name,age){ 2 this.name = name; 3 this.age = age; 4 this.sayName = function(){ 5 console.log(this.name); 6 } 7 } 8 var people1 = new People("yewenxiang",24); 9 var people2 = new People("yewenxiang",23); 10 console.log(people1.sayName == people2.sayName); //false 11 console.log(people1.sayName() == people2.sayName()); //true
我们创建的每个函数都有一个prototype属性,这个属性是一个指针,指向了原型对象。这个原型对象的作用是由自定义的构造函数所有实例化的对象共享的属性和方法.
1 function People(){ 2 } 3 People.prototype.name = "yewenxiang"; 4 People.prototype.age = "23"; 5 People.prototype.sayName = function(){ 6 console.log(this.name); 7 } 8 var people1 = new People(); 9 var people2 = new People(); 10 console.log(people1.sayName == people2.sayName); // true
用一个包含所有属性和方法的对象字面量来重写整个原型。
1 function People(){ 2 } 3 People.prototype = { 4 name:"yewenxiang", 5 age:24, 6 sayName:function(){ 7 console.log(this.name); 8 } 9 };
但是有个问题,因为是用对象字面量来重写了People.prototype对象,People.prototype.constructor 指向了Object这个构造函数,不再指向People构造函数,如下图虚线为变化前,实线为变化后。
1 function People(){ 2 } 3 People.prototype = { 4 name:"yewenxiang", 5 age:24, 6 sayName:function(){ 7 console.log(this.name); 8 } 9 } 10 var people1 = new People(); 11 console.log(people1.prototype); 12 console.log(People.prototype.constructor); //输出Object构造函数 13 console.log(people1 instanceof People); //true 14 console.log(people1 instanceof Object); //true
虽然可以使用instanceof 来检测对象的类型,但是无法使用people1.constructor 来确定对象了,因为所有实例都会使用People.prototype原型上的constructor属性,而这个属性指向Object构造函数。
instanceof 检测的原理:
可以给People.prototype = {constructor:People}来解决这个问题,但是重设了constructor属性的值,导致他变成了可枚举的状态,原生的是不可枚举的,可以使用Object.defineProperty来定义这个属性
1 function People(){ 2 } 3 People.prototype = { 4 name:"yewenxiang", 5 age:24, 6 sayName:function(){ 7 console.log(this.name); 8 } 9 } 10 Object.defineProperty(People.prototype,"constructor",{ 11 enumerable:false, // 不可枚举 12 value:People 13 }); 14 var people1 = new People(); 15 console.log(people1.prototype); 16 console.log(people1.constructor); //输出People构造函数 17 console.log(people1 instanceof People); //true 18 console.log(people1 instanceof Object); //true
原型模式的问题:
使用的技巧:
1 function People(name,age){ 2 this.name = name; 3 this.age = age; 4 } 5 People.prototype.sayName = function(){ 6 console.log(this.name); 7 } 8 var people1 = new People("yewenxiang",24);
标签:虚线 技巧 方法 images 构造函数 style 参数 console 使用
原文地址:http://www.cnblogs.com/yewenxiang/p/6204575.html