原型及原型链
原型-prororype
函数的prototype属性
- 每个函数都有一个prototype属性--默认指向一个Object空对象--即原型对象
console.log(Date.prototype, typeof Date.prototype);//Date函数中包含了自身的方法
function fn() {};
console.log(fn.prototype, typeof fn.prototype);
- 原型对象中有一个属性constructor--指向函数对象
function fn() { };
console.log(fn.prototype, typeof fn.prototype);
console.log(fn.prototype.constructor === fn);
- 给原型对象添加属性--一般是方法--实例对象可以访问
- 函数中所有实例对象自动拥有原型中的属性
function fn() { };
fn.prototype.test = function () {
console.log('test');
};
let fns = new fn();
fns.test(); //test
显式原型与隐式原型
-
每个函数function都有一个prototype--即显式原型(属性)
-
每个实例对象都有一个_ _ proto _ _ --称为隐式原型(属性)
-
对象的隐式原型的值为其对应构造函数的显性原型的值
//定义构造函数 function fn() { //内部语句--this.prototype = {}; } console.log(fn.prototype); //创建实例对象 let fns = new fn(); //内部语句--fns.__proto__ = fn.prototype console.log(fns.__proto__); console.log(fns.__proto__ === fn.prototype); //给原型添加方法 fn.prototype.test = function () { console.log('原型方法'); } //通过实例调用原型的方法 fns.test();
- 内存结构
- 总结
- 函数的prototype属性--在定义函数时自动添加的--默认值是一个空Object对象
- 对象的__ proto __ 属性--在创建对象时自动添加的--默认值为构造函数的prototype属性值
- 程序员能直接操作显式原型--不能直接操作隐式原型--ES6之前
原型链
-
访问一个对象的属性时
- 先在自身属性中查找--找到返回
- 若找不到--沿着__ proto __ 这条链向上查找--找到返回
- 若最终没有找到--返回undefined
-
原型链--别名--隐式原型链
- 作用--查找对象的属性(方法)
-
构造函数/原型/实体对象的关系
- 构造函数/原型/实体对象的关系2
补充
- 函数的显示原型指向的对象--默认是空的object实例对象--但object除外
function fn(){};
console.log(fn.prototype instanceof Object); //true
console.log(Object.prototype instanceof Object); //false
console.log(Function.prototype instanceof Object); //true
- 所有函数都是Function的实例--包括Function本身
function fn(){};
console.log(Function.__proto__ === Function.prototype); //true
console.log(fn.__proto__ === Function.prototype); //true
- Object的原型对象是原型链的尽头
console.log(Object.prototype.__proto__); //null
属性问题
-
读取对象的属性值时--会自动到原型链中查找
-
设置对象的属性值时--不会查找原型链--若当前对象中没有此值--直接添加此属性并设置其值
-
方法一般定义在原型中--属性一般通过构造函数定义在对象本身
function Fn() {
}
Fn.prototype.a = '枣';
let fn1 = new Fn();
console.log(fn1.a, fn1); //枣 Fn{}
let fn2 = new Fn();
fn2.a = 'zao';
console.log(fn2.a, fn2); //zao Fn{a:zao}
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.setName = function (name) {
this.name = name;
}
let p1 = new Person('Levi', 22);
console.log(p1); //'Levi', 22
p1.setName('zaoya'); //zaoya 22
console.log(p1);
let p2 = new Person('小枣', 18);
console.log(p2);
console.log(p1.__proto__ === p2.__proto__);//true