
一、基本概念
【原型链】每个构造函数都有一个对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么,如果原型对象等于另一个原型的实例,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。如果另一个原型又是另一个原型的实例,那么上述关系依然成立。如此层层递进,就构成了实例与原型的链条。
【原型对象】这个对象包含可以由特定类型的所有实例共享的属性和方法。所有引用类型默认都继承了Object,而这个继承也是通过原型链实现的。所有函数的默认原型都是Object的实例,因此默认原型都会包含一个内部指针,指向Object.prototype,这也正是所有自定义类型都会继承toString()、valueOf()方法的原因
【构造函数】构造函数与其他函数的区别在于调用它们的方式不同。一般来说,函数只要通过new操作符来调用,那它就可以作为构造函数;如果不通过new操作符来调用,那它跟普通函数也不会有什么两样。
[注意]用户自定义的函数和javascript中内置的构造函数可以当成构造函数使用
【构造函数的写法】构造函数始终应该以一个大写字母开头,而非构造函数以一个小写字母开头。这个做法借鉴自其他OO语言,主要是为了区别于ECMAScript中的其他函数;因为构造函数本身也是函数,只不过可以用来创建对象而已
【构造函数的三种使用场景】
[a]当作构造函数使用
var person = new Person("Nicholas",29,"software Engineer");person.sayName();[b]当作普通函数调用
Person("greg",27,"doctor");//添加到windowwindow.sayName();//"Greg"[c]在另一个对象的作用域中调用
var o = new Object();Person.call(o,"Kristen",25,"Nurse");o.sayName();//"Kristen"【prototype属性】只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。
function Person(){};var friend = new Person();Person.prototype.sayHi = function(){alert("hi");}friend.sayHi();//"hi"【重写原型】调用构造函数时会为实例添加一个指向最初原型的[[prototype]]指针,而把原型修改为另外一个对象就等于切断了构造函数与最初原型之间的联系。实例中的指针仅指向原型,而不指向构造函数。function Person(){};var person1 = new Person();var person2 = new Object();console.log(Person.prototype.isPrototypeOf(person1));//trueconsole.log(Object.prototype.isPrototypeOf(person1));//trueconsole.log(Person.prototype.isPrototypeOf(person2));//falseconsole.log(Object.prototype.isPrototypeOf(person2));//true[2]ECMAScript5新增方法Object.getPrototypeOf():这个方法返回[[Prototype]]的值function Person(){};var person1 = new Person();var person2 = new Object();console.log(Object.getPrototypeOf(person1)); //Person{}console.log(Object.getPrototypeOf(person1) === Person.prototype); //trueconsole.log(Object.getPrototypeOf(person1) === Object.prototype); //falseconsole.log(Object.getPrototypeOf(person2)); //Object{}[3]hasOwnProperty():检测一个属性是否存在于实例中function Person(){Person.prototype.name = "Nicholas";}var person1 = new Person();//不存在实例中,但存在原型中console.log(person1.hasOwnProperty("name"));//false//不存在实例中,也不存在原型中console.log(person1.hasOwnProperty("no"));//falseperson1.name = "Greg";console.log(person1.name);//"Greg"console.log(person1.hasOwnProperty("name"));//truedelete person1.name;console.log(person1.name);//"Nicholas"console.log(person1.hasOwnProperty("name"));//false[4]ECMAScript5的Object.getOwnPropertyDescriptor():只能用于取得实例属性的描述符,要取得原型属性的描述符,必须直接在原型对象上调用Object.getOwnPropertyDescription()方法function Person(){Person.prototype.name = "Nicholas";}var person1 = new Person();person1.name = "cook";console.log(Object.getOwnPropertyDescriptor(person1,"name"));//Object {value: "cook", writable: true, enumerable: true, configurable: true}console.log(Object.getOwnPropertyDescriptor(Person.prototype,"name"));//Object {value: "Nicholas", writable: true, enumerable: true, configurable: true}[5]in操作符:在通过对象能够访问给定属性时返回true,无论该属性存在于实例还是原型中function Person(){}var person1 = new Person();person1.name = "cook";console.log("name" in person1);//trueconsole.log("name" in Person.prototype);//falsevar person2 = new Person();Person.prototype.name = "cook";console.log("name" in person2);//trueconsole.log("name" in Person.prototype);//true[6]同时使用hasOwnProperty()方法和in操作符,来确定属性是否存在于实例中//hasOwnProperty()返回false,且in操作符返回true,则函数返回true,判定是原型中的属性function hasPrototypeProperty(object,name){return !object.hasOwnProperty(name) && (name in object);}function Person(){Person.prototype.name = "Nicholas";}var person1 = new Person();console.log(hasPrototypeProperty(person1,"name"));//trueperson1.name = "cook";console.log(hasPrototypeProperty(person1,"name"));//falsedelete person1.name;console.log(hasPrototypeProperty(person1,"name"));//truedelete Person.prototype.name;console.log(hasPrototypeProperty(person1,"name"));//false[7]ECMAScript5的Object.keys()方法:接收一个对象作为参数,返回一个包含所有可枚举属性的字符串数组function Person(){Person.prototype.name = "Nicholas";Person.prototype.age = 29;Person.prototype.job = "Software Engineer";Person.prototype.sayName = function(){alert(this.name);}};var keys = Object.keys(Person.prototype);console.log(keys);//[]var p1 = new Person();p1.name = "Rob";p1.age = 31;var keys = Object.keys(Person.prototype);console.log(keys);//["name","age","job","sayName"]var p1Keys = Object.keys(p1);console.log(p1Keys);//["name","age"][8]ECMAScript5的Object.getOwnPropertyNames()方法:接收一个对象作为参数,返回一个包含所有属性的字符串数组function Person(){Person.prototype.name = "Nicholas";Person.prototype.age = 29;Person.prototype.job = "Software Engineer";Person.prototype.sayName = function(){alert(this.name);}};var keys = Object.getOwnPropertyNames(Person.prototype);console.log(keys);//["constructor"]var p1 = new Person();var keys = Object.getOwnPropertyNames(Person.prototype);console.log(keys);//["constructor", "name", "age", "job", "sayName"]希望本文所述对大家学习javascript程序设计有所帮助。