Object模式
创建一个Object实例,再为其添加属性和方法。
这是创建自定义对象最简单的方式。
1.创建对象
// 创建person对象var person = new Object();person.name = "Mike";person.age = 20;person.job = "student";person.showName = function(){ console.log("this.name = " + this.name);};person.consThis = function(){ console.log("this = "); console.log(this); // this指向person对象 console.log(this === person);};person.showName();person.consThis();
输出如图:
2.观察下person.showName属性引用的函数
// person.showName引用的是一个匿名函数,其name属性为""console.log("person.showName.name=");console.log(person.showName.name);console.log(person.showName.name === "")console.log("-----分割线-----");// showName引用的匿名函数的prototype属性指向其原型对象console.log("person.showName.prototype=");console.log(person.showName.prototype);console.log(person.showName.prototype === Function.prototype); //不是Function构造函数的原型对象console.log("-----分割线-----");//其原型对象的constructor属性指向showName引用的匿名函数console.log("person.showName.prototype.constructor="); console.log(person.showName.prototype.constructor); console.log("-----分割线-----");// 此匿名函数的原型对象的__proto__属性指向Object构造函数的原型对象console.log("person.showName.prototype.__proto__=");console.log(person.showName.prototype.__proto__);console.log(person.showName.prototype.__proto__ === Object.prototype);console.log("-----分割线-----");// showName引用的匿名函数的__proto__属性指向Function.prototypeconsole.log("person.showName.__proto__="); //showName引用的是一个匿名函数,匿名函数本质上是由构造函数Function生成的console.log(person.showName.__proto__); //showName引用的是一个匿名函数,匿名函数本质上是由构造函数Function生成的// 验证console.log(person.showName.__proto__ === Function.prototype); //trueconsole.log("-----分割线-----");
showName
属性引用的匿名函数信息:
输出如图:
3.观察person对象涉及到的原型链
Object
构造函数的原型链
// prototype属性指向Object构造函数的原型对象console.log("Object.prototype=");console.log(Object.prototype);// Object构造函数的原型对象的constructor属性指向其本身console.log("Object.prototype.constructor=");console.log(Object.prototype.constructor);console.log("-----分割线-----");//所有构造函数(内置及自定义)的__proto__属性都指向Function构造函数的原型对象// __proto__指向Function构造函数的原型对象,即Function.prototypeconsole.log("Object.__proto__=");console.log(Object.__proto__); console.log(Object.__proto__ === Function.prototype); console.log("-----分割线-----");
person
对象的原型链
// person是对象,非函数,所以没有prototype属性console.log("person.prototype=");console.log(person.prototype);console.log("-----分割线-----");// 所有对象的__proto__都指向其构造器的prototype// person的__proto__属性指向构造函数的原型对象,即Object构造函数的原型对象console.log("person.__proto__=");console.log(person.__proto__);// 验证console.log(person.__proto__ === Object.prototype) //trueconsole.log("-----分割线-----");
构造函数的原型对象的类型
// Function.prototype的类型为functionconsole.log("typeof Function.prototype:");console.log(typeof Function.prototype); // 除了Function构造函数的原型对象为function,其他构造函数的原型对象类型为object// Object.prototype的类型为objectconsole.log("typeof Object.prototype:");console.log(typeof Object.prototype);// Array.prototype的类型为objectconsole.log("typeof Array.prototype:");console.log(typeof Array.prototype);console.log("-----分割线-----");
Function构造函数的原型对象和Object构造函数的原型对象的关系
// Function.prototype.__proto指向Objcet.prototypeconsole.log("Function.prototype.__proto__=");console.log(Function.prototype.__proto__);// 验证console.log(Function.prototype.__proto__ === Object.prototype); //true// 这说明所有的构造器也都是一个普通JS对象,可以给构造器添加/删除属性等。同时它也继承了Object.prototype上的所有方法:toString、valueOf、hasOwnProperty等。console.log("-----分割线-----");// Object.prototype.__proto指向nullconsole.log("Object.prototype.__proto__=");console.log(Object.prototype.__proto__);// 原型链到顶了,为null。
原型分析
所有构造器/函数的_ proto _都指向Function.prototype
所有对象的_ proto _都指向其构造器的prototype
除了Function构造函数的原型对象为function,其他构造函数的原型对象类型为object
所有的构造器也都是一个普通JS对象,可以给构造器添加/删除属性等。同时它也继承了Object.prototype上的所有方法:toString、valueOf、hasOwnProperty等。
person对象是由Object构造函数创建而成的,所以它的_ proto _指向Object.prototype
原型链图
person对象的原型链图:
person对象showName属性引用的匿名函数的原型链图: