属性类型
- 数据属性
var person = {}; Object.defineProperty(person, 'name', { value: 'Chengjie ZHANG', writable: false, //是否可修改(只读) enumerable: false, //是否可枚举,false则不能被for-in检测到 configurable: false //一旦是false,那就不能再被还原成true了 });Object.defineProperty()可以对一个property使用多次 - 访问器属性
var person = {}; Object.defineProperty(person, 'name', { get: function(){ return this.name; }, set: function(val){ this.name = val; } });
Vue 2.0的双向数据绑定就是这样实现的。详见Vue笔记
原型模式
//由于ES中函数也是对象,所以成员函数写在构造函数里面的话,每个实例对象的成员函数都被重复实例化了。 person1.say() == person2.say() //false
__proto__(隐式原型)与prototype(显式原型)
两者关系:实例对象的是隐式的,函数对象是显示的。
prototype显式原型的作用:用来实现基于原型的继承与属性的共享。
__proto__隐式原型的作用:构成原型链,同样用于实现基于原型的继承。大多数浏览器都支持通过__proto__来访问。ES5新增Object.getPrototypeOf(obj).
1. prototype(显式原型)
Person.prototype最初只有包含constructor一个属性
in操作符只要对象能够访问到就返回true
hasOwnProperty()存在与对象实例本身,而不存在于原型上
hasPrototypeProperty()存在于对象的原型上。
原型屏蔽问题
var person = new Person(); alert( "name" in person ); //true alert( Object.prototype.hasOwnProperty(p, 'name') ); //false
2. __proto__(隐式原型)
在调用person1.sayName()的时候:
- person1下面有没有sayName? 没有
- person1.__proto__指向Person Prototype下有没有sayName?有的,返回sayName
- sayName()执行
存在一个原型动态性的问题
function Person(){ }
var friend = new Person();
Person.prototype = {
constructor: Person,
name: 'myName',
sayName: function (){
console.log(this.name);
}
};
Person.prototype.sayHi = function(){
alert("hi");
};
friend.sayHi(); //"hi"(没有问题!)
friend.sayName(); //error
继承
*核心:SubType.prototype = new SuperType(); *
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function(){
return this.property;
};
function SubType(){
this.subproperty = false;
}
//继承了 SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function (){
return this.subproperty;
};
var instance = new SubType();
alert(instance.getSuperValue()); //true组合继承模式(原型链+借用构造函数)
使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。
也叫做伪经典继承,指的是将原型链和借用构造函数的技术组合到一块,从而发挥二者之长的一种继承模式。
这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有它自己的属性。如果是想要用静态属性的话,就把属性挂在原型链上
function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
function SubType(name, age){
SuperType.call(this, name); //继承属性,确保colors独立
this.age = age;
}
SubType.prototype = new SuperType(); //继承方法
SubType.prototype.constructor = SubType; //实例对象指回自己,因为有age属性,朴素原型继承法里,prototype是没有constructor的
SubType.prototype.sayAge = function(){
alert(this.age);
};
var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29
var instance2 = new SubType("Greg", 27);
alert(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27 

京公网安备 11010502036488号