定义与实例化
function Person(){
}
// 定义原型链上的属性
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
console.log(this.name);
};
// 两个实例,都是调用的原型链上的函数
var person1 = new Person();
person1.sayName(); //"Nicholas"
var person2 = new Person();
person2.sayName(); //"Nicholas"
console.log(person1.sayName == person2.sayName); //true
console.log(Person.prototype.isPrototypeOf(person1)); //true
console.log(Person.prototype.isPrototypeOf(person2)); //true
// only works if Object.getPrototypeOf() is available
if (Object.getPrototypeOf){
console.log(Object.getPrototypeOf(person1) == Person.prototype); //true
console.log(Object.getPrototypeOf(person1).name); //"Nicholas"
}
实例属性与原型链属性
person1.name = "Greg"; // 实例上定义了属性
alert(person1.name); //"Greg" 从实例上的属性获取
alert(person2.name); //"Nicholas" 从实例的原型链上获取
delete 操作
// 两个实例-测试 delete 操作
var person1 = new Person();
var person2 = new Person();
person1.name = "Greg";
console.log(person1.name); //"Greg" – from instance
console.log(person2.name); //"Nicholas" – from prototype
delete person1.name; // 删除的是实例上的,但还有 prototype 上的
delete person1.name; // delete 只会删除实例上的属性,不会删除原型链上的
console.log(person1.name); //"Nicholas" - from the prototype
判断属性是实例上的还是原型链上的
var person1 = new Person();
var person2 = new Person();
console.log(person1.hasOwnProperty("name")); //false
// in 方法会同时判断 实例 和 原型链 上
console.log("name" in person1); //true
//
person1.name = "Greg";
console.log(person1.name); //"Greg" – from instance
// hasOwnProperty 判断实例上是否有指定的属性
console.log(person1.hasOwnProperty("name")); //true
console.log("name" in person1); //true
//
console.log(person2.name); //"Nicholas" – from prototype
console.log(person2.hasOwnProperty("name")); //false
console.log("name" in person2); //true
// delete 会删除实例上的属性,不会删除原型链上的
delete person1.name;
console.log(person1.name); //"Nicholas" - from the prototype
console.log(person1.hasOwnProperty("name")); //false
console.log("name" in person1); //true
// 定义函数实现
// 判断 实例的原型链上是否存在指定的属性
function hasPrototypeProperty(object, name){
return !object.hasOwnProperty(name) && (name in object);
}
实例类型判断
var friend = new Person();
// 判断实例的类型
console.log(friend instanceof Object); //true
console.log(friend instanceof Person); //true
// 构造函数默认的定义为 objects
console.log(friend.constructor == Person); //false
console.log(friend.constructor == Object); //true
指定构造函数,导致上面类型判断不一样
Person.prototype = {
// 构造原型定义 - 如果不指定,则默认是 object
constructor : Person,
name : "Nicholas",
age : 29,
job: "Software Engineer",
sayName : function () {
alert(this.name);
}
};
alert(friend.constructor == Person); //true
alert(friend.constructor == Object); //false
实例化之后添加原型链函数
function Person(){}
Person.prototype = {
constructor: Person,
name : "Nicholas",
age : 29,
job : "Software Engineer",
sayName : function () {
console.log(this.name);
}
};
var friend = new Person();
// 在实例化之后,原型链上添加新的函数,实例上可直接调用
Person.prototype.sayHi = function(){
console.log("hi");
};
friend.sayHi(); //"hi" – works!
实例化之后,再定义 原型链属性
function Person(){}
var friend = new Person();
// 在实例化之后,重新定义 原型链属性、构造、函数,则实例无法调用相关函数
Person.prototype = {
constructor: Person,
name : "Nicholas",
age : 29,
job : "Software Engineer",
sayName : function () {
alert(this.name);
}
};
console.log(friend.name); //undefined
friend.sayName(); //error
无法理解的原型链
function Person(){}
Person.prototype = {
constructor: Person,
name : "Nicholas",
age : 29,
job : "Software Engineer",
friends : ["Shelby", "Court"],
sayName : function () {
console.log(this.name);
}
};
var person1 = new Person();
var person2 = new Person();
person1.friends.push("Van");
// 正常的理解应该是互不相关的两个实例,但他们原型链上的数组却一样了
// 无法理解!!!
console.log(person1.friends); //"Shelby,Court,Van"
console.log(person2.friends); //"Shelby,Court,Van"
console.log(person1.friends === person2.friends); //true