JS prototype简单理解

456 阅读2分钟

前端新手的理解,多多包含,如有不对请在评论区指出.

首先说一下prototype

在javascript中prototype是用来捆绑儿子和父亲的关系。
一个对象天生就有prototype,而这个prototype就是object。

对象的结构

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.eat = function () {
        console.log(`${this.name}吃饭了`)
    }
}

//在constructor创建属性和方法
Person["language"] = "简体中文";
Person["jump"] = function () {
    console.log(`跳跃了`)
}

//在prototype创建属性和方法
Person.prototype["country"] = "中国";
Person.prototype["study"] = function () {
    console.log(`${this.name}学习了`)
}

//创建lisi对象
let lisi = new Person("lisi", 18);

//创建zs对象
let zs = new Person("Zhangsan", 90);
zs.country = "新加坡"; //修改国家

console.log(lisi);
console.log(zs);

控制台结果

从输出结果我们可以得出以下结论:

  1. 使用 [函数名].prototype[属性或方法] 声明的方法和属性是在__proto__中.
  2. 使用[函数名][属性或方法]是在__proto__constructor中,这里声明的属性和方法只能以[函数名].[属性或方法]进行调用.

实例的__proto__和函数的prototype

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.eat = function () {
        console.log(`${this.name}吃饭了`)
    }
}

//在constructor创建属性和方法
Person["language"] = "简体中文";
Person["jump"] = function () {
    console.log(`跳跃了`)
}

//在prototype创建属性和方法
Person.prototype["country"] = "中国";
Person.prototype["study"] = function () {
    console.log(`${this.name}学习了`)
}

//创建lisi对象
let lisi = new Person("lisi", 18);

console.log(lisi.__proto__);
console.log(Person.prototype);
console.log(lisi.__proto__ === Person.prototype);  //结果true

控制台结果

从输出结果我们可以得出以下结论:

  1. 实例的__proto__[函数名].prototype结构是一样的,并且lisi.__proto__ === Person.prototypetrue
  2. 实例的__proto__[函数名].prototype__proto__都是Object。

protoType的属性和方法

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.eat = function () {
        console.log(`${this.name}吃饭了`)
    }
}

//在prototype创建属性和方法
Person.prototype["country"] = "中国";
Person.prototype["study"] = function () {
    return `${this.name}学习了`;
}

//创建lisi对象
let lisi = new Person("lisi", 18);

console.log("国家是:" + lisi.country);  //中国
console.log(`今天${lisi.study()}`);  //今天lisi学习了

let zs = new Person("zs", 90);

console.log(zs.eat === lisi.eat);  //fase
console.log(zs.__proto__ === lisi.__proto__);  //true
console.log(zs.study === lisi.study);  //true

控制台结果

从输出结果我们可以得出以下结论:

  1. 当在实例中找不到属性或方式时会从prototype中进行查找,所以prototype的属性和方法具有继承性.
  2. 两个实例的方法是不相等的。两个实例的prototype是相等的,所以可以得到两个实例的prototype方法是相等的。

prototype和constructor总结

  1. prototype的属性和方法具有继承性
  2. 多个实例的prototype是相等的,(所以可以得到多个实例的prototype方法是相等的),这样的方式可以减少内存。
  3. 实例的__proto__和函数的prototype是相等的
  4. constructor的属性和方法只能被函数本身调用。