6.1对象
- 对象的属性,包括两种,数据属性和访问器属性。
- 使用Object.defineProperty可以同时定义多个属性,这是只能传入两个参数,第一个是对象实例,第二个是表示属性的json。
- 使用Object.getOwnPropertyDescriptor(object,propertyName),可以返回对象实例某个属性的配置
6.2构造函数
- 工厂模式
- 工厂模式的优点是简单方便易用好理解,缺点是无法对对象进行识别,即不能判断对象实例的类型。
function createCar(name, value){
var o = new Object();
o.name=name;
o._value=value;
o.getValue=function(){return this._value;}
o.setValue=function(v){this._value=v;}
return o;
}
var mycar=createCar("BMW",10000);
- 构造函数模式
- 与工厂模式的区别:1.没有显式地创建对象,即没有new object; 2.直接将属性和方法赋给this对象;3.没有return对象
- 构造函数首字母大写;
- 使用构造函数模式,必须使用new操作符。创建后,构造函数的this指针指向了新对象;
- 可以用constructor判断一个实例的构造函数,也可以用instanceof判断。
- 也可以使用函数的apply或者call来使用构造函数;
- 缺点:如果是实例方法,不同实例化,他们的方法地址是不一样,是唯一的;
function Car(name,value){
this.name=name;
this._value=value;
this.getValue=function(){return this._value;}
this.setValue=function(v){this._value=v;}
}
//当构造函数使用
var myCar = new Car("BMW",10000);
//在另一个对象的作用域中调用
var myCar2= new Object();
Car.apply(myCar2,["BMW2",10001]);
alert(myCar.constructor==Car);//true
alert(myCar instanceof Car);//true
alert(myCar instanceof Object);//true
alert(myCar2.getValue());//10001
- 缺点:如果是实例方法,不同实例化,他们的方法地址是不一样,是唯一的;
var car1=new Car("BMW",10000);
var car2=new Car("BMW",10001);
alert(car1.getValue==car2.getValue);//false
解决
function CarBMW(owner,value){
this.owner=owner;
this._value=value;
this.getValue=_CarBMW_getValue;
this.setValue=_CarBMW_setValue;
}
function _CarBMW_getValue(){
return this._value;
}
function _CarBMW_setValue(v){
this._value=v;
}
var car3=new CarBMW("Brain",10000);
var car4=new CarBMW("Join",10001);
alert(car3.getValue==car4.getValue);//true
- 原型模式、
我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个对象,它的用途是包含可以由特定类型的所有实例共享的属性和方法。换句话说,prototype就是通过调用构造函数而创建的那个对象的原型对象。使用它的好处是可以让所有的对象实例共享它所包含的属性和方法。
function Person(){}
Person.prototype.name = ‘yy’;
Person.prototype.age = 29;
Person.prorotype.sayName = function(){
alert(this.name);
}
var person1 = new Person();
person1.sayName(); // outputyy
- 理解原型:
无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性。在默认的情况下,所有prototype属性都会自动获得一个constructor属性,这个属性包含一个指向prototype属性函数的指针。 - 原型与in操作符:in操作符会在通过对象能够访问给定属性时返回true,无论属性存在实例还是原型;
- 更简单的原型语法:
function Person(){}
Person.prototype = {
name: ‘yy’,
age: 29,
sayName: function(){
alert(this.name);
}
}
- 原型的动态性:重写原型会切断现有原型与任何之前已经存在的对象实例之间的联系,虽然它们引用的仍然是最初的原型;
- 原生对象的原型:可以扩展原生对象的方法
String.prototype.startWith = function(){
return this.indexOf(text) == 0;
}
var msg = ‘hello world’;
alert(msg.startWith(‘hello’)); //output true
- 原型对象的问题
:原型中所有属性被很多的实例共享,对于包含引用类型的属性来说,就不怎么乐观。
-
组合使用构造函数模式和原型模式
:构造函数模式用于定义实例属性,而原型模式用于定义方法和属性;
function Car(name,value){
this.name=name;
this._value=value;
}
Car.prototype={
constructor:Car,
getValue:function(){return this._value;},
setValue:function(v){this._value=v;}
}