什么是原型链:
每一个对象都有自己的原型,而原型也是对象,也有自己的原型,一次类推而形成的链式结构就叫做原型链
对象访问原型链中的成员采用就近原则
1.如果自己本身有就去自己的,如果自己没有就从原型中找,如果原型中也没有就从原型的原型中找,一次类推知道找到原型链的终点null,如果还没有找到是属性就返回undefined , 如果是方法就返回xxx is not a function.
js中的对象都是由构造函数创建的
1.自定义构造函数
function Person(name,age){
this.name = name;
this.age = age;
};
//每一个人都可以打招呼,可以添加到原型中
Person.prototype.sayHi = function(){
console.log('今天六一儿童节,今晚请你洗剪吹');
};
//人类属于哺乳动物,可以添加到原型中
Person.prototype.type = '哺乳动物';
var p1 = new Person('班长',20);
console.log(p1);
/*面试题 :请说出下面程序运行的结果
*/
console.log(p1.name);//班长 p1自己有name属性
console.log(p1.type);//哺乳动物 p1自己虽然没有type属性,但是它的原型有type
p1.sayHi();// p1自己虽然没有sayHi方法,但是它的原型有
//对象取值:不存在undefined
console.log(p1.girlFriend);//undefined p1自己没有girlFriend,原型也没有,
//p1.eat();//程序报错 eat is not a function p1自己没有eat方法,原型也没有,
//为什么不报错? p1自己没有toString p1的原型也没有toString 但是p1的原型的原型有toString
console.log(p1.toString());
//1.查看p1的原型
console.log(p1.__proto__.constructor);//Person
console.log(p1.__proto__ === Person.prototype);//true
//2.查看p1原型的原型
console.log( p1.__proto__.__proto__.constructor);//Object
console.log( p1.__proto__.__proto__ === Object.prototype);//true
//3,查看p1的原型的原型的原型
console.log(p1.__proto__.__proto__.__proto__);//null
2.查看内置对象的原型链
//1.Array对象
var arr = [10,20,30];// new Array(10,20,30)
//查看数组对象的原型链
console.log(arr.__proto__.constructor);//Array
console.log(arr.__proto__ === Array.prototype);//true
//查看数组对象的原型的原型
console.log(arr.__proto__.__proto__.constructor);//Object
console.log(arr.__proto__.__proto__ === Object.prototype);//true
console.log(arr.__proto__.__proto__.__proto__);//null
console.log(arr);
arr.push();//js作者将数组所有的API都放入了Array。prototype中,这样所有的数组对象都可以直接调用
arr.toString();//所有的对象原型链都会指向Object.prototype,这就意味着任何对象都可以调用Object原型中的方法
//2.Date对象
var date = new Date();
细节:日期对象不能直接用log,会自动转成toString字符串
console.log(date);
//查看对象内存空间 console.dir()
console.dir(date);
//查看date的原型
console.log(date.__proto__.constructor);//Date
console.log(date.__proto__ === Date.prototype);//true
//查看date的原型的原型链
console.log(date.__proto__.__proto__.constructor);//Object
console.log(date.__proto__.__proto__ === Object.prototype);//true
//3.String对象(基本包装类型 new String new Number new Boolean)
var str = new String('123');
console.log(str);
//查看str对象的原型
console.log(str.__proto__.constructor);//String
console.log(str.__proto__ === String.prototype);//true
//查看str对象原型的原型
console.log(str.__proto__.__proto__.constructor);//Object
console.log(str.__proto__.__proto__ === Object.prototype);//true
//4.DOM对象
var box = document.getElementById('box');
var p1 = document.getElementById('p1');
console.log(box);//打印HinnerHTML
console.dir(box);//打印对象内存空间
console.dir(p1);
3.函数也是对象类型:
验证:对象拥有点语法动态添加属性,如果函数也能像对象一样拥有点语法动态添加属性**
function fn(){
console.log('11111');
};
fn.sb = function(){
console.log('一群大雁飞过,一会儿拍成了s形,一会儿又拍成了b形');
};
fn.aaa = '我是函数的属性';
fn.sb();
console.log(fn.aaa);
//log:打印函数中存储的代码
console.log(fn);
//dir:打印函数对象中存储的属性
console.dir(fn);
//2.既然函数也是对象(所有的对象都是构造函数创建),那么函数对象又是谁创建的呢?
/* 函数是一个特殊的对象,所有的函数都是由Function构造函数创建 */
console.log(fn.__proto__.constructor);//Function
console.log(fn.__proto__ === Function.prototype);//true
console.log(Object.__proto__.constructor);//Function
console.log(Array.__proto__.constructor);//Function
由上面的介绍基本上已经可以大概了解原型链的雏形啦,下面就是原型链的完整版
由原型对象看instanceof
<script>
/*
instanceof运算符工作原理: 对象 instanceof 构造函数
规则: 检查右边构造函数的原型,在不在左边对象的原型链中
*/
//1.Array
/*根据instanceof的运算规则: 左边Array是对象,右边是构造函数
Array构造函数对象的原型链:Array对象.__proto__ -> Function.prototype -> Object.prototype -> null
*/
console.log(Array instanceof Object);//true
console.log(Array instanceof Function);//true
console.log(Array instanceof Array);//false
//2.Function
/*
根据instanceof运算符规则:左边Function是对象,右边的Function是构造函数
Function对象的完整原型链: Function -> Function.prototype - > Object.prototype -> nulll
*/
console.log(Function instanceof Function);//true
console.log(Function instanceof Object);//true
//3.Object
/*
根据instanceof运算符规则:左边Object是对象,右边的Object是构造函数
Object对象的完整原型链: Object -> Function.prototype - > Object.prototype -> nulll
*/
console.log(Object instanceof Function);//true
console.log(Object instanceof Object);//true
</script>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。