原型及原型链

原型-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
posted @ 2023-04-18 22:34  Liu-h  阅读(16)  评论(0编辑  收藏  举报