原型和原型链

构造函数

构造函数首字母需要大写,并且会默认返回this

function Person(name){
	this.name = name;
	return this; //默认返回,省略
}

prototype 原型

一个对象被其他对象实例继承时,其在原型上定义的属性,通过“继承”,来拥有该对象原型上定义的属性,继承的行为时通过 new 操作符内部实现的

并且每一个构造器函数内部都有一个名为prototype的属性,通过这个属性就可以访问到原型
在这里插入图片描述

proto 隐式原型

在引用类型中,隐式原型 __proto__的属性指向她的构造器函数的显示原型prototype的属性值

let obj = {};
let arr = [];
let fnnc = function() {}

obj.__proto__ == Object.prototype // true
arr.__proto__ === Array.prototype // true
fnnc.__proto__ == Function.prototype // true

instanceof

检查是否该对象为该构造器的实例
手写简易的instanceof

  • 排除基本类型
  • 取sup的显示原型和sub的隐式原型对比,严格相同则返回
  • 循环寻找sub的隐式原型,直到最顶层,为null则退出
        function myInstanceof(sub, sup) {
            const baseType = ['string', 'number', 'boolean', 'undefined', 'symbol'];
            if (baseType.includes(typeof (sub))) return false;

            let supPro = sup.prototype;
            sub = sub.__proto__;
            while (true) {
                if (sub === null) return false;
                if (sub === supPro) return true;
                sub = sub.__proto__;
            }
        }

        function Person(name) {
            this.name = name
        }

        var person = new Person('mike');
        console.log(myInstanceof(person, Person)); //true
        console.log(myInstanceof(person, Object)); //true

手写new

function mynew(Func, ...args) {
    // 1.创建一个新对象
    const obj = {}
    // 2.新对象原型指向构造函数原型对象
    obj.__proto__ = Func.prototype
    // 3.将构建函数的this指向新对象
    let result = Func.apply(obj, args)
    // 4.根据返回值判断
    return result instanceof Object ? result : obj
}

constructor

这里constructor是原型的一个属性。用于获取原型的构造器函数

        function Person(name) {
            this.name = name
        }

        var person = new Person('mike');

        console.log(Person.prototype.constructor===Person);  //true

原型链

在这里插入图片描述

实例、构造函数、原型之间的关系

在这里插入图片描述
每个构造函数都有一个原型对象prototype,原型有一个属性constructor指回构造函数,而实例有一个内部指针__proto__指向原型。

Class

  • Class只是一个语法糖,让对象原型写法更加清晰
  • Class内部定义的方法不需要function关键字;方法间不需要分号;须使用new来调用
  • Class类内所有的方法都定义在Class 类的prototype上
  • this 关键字指向类的实例对象,this 上显示定义的属性即定义在实例对象上
// 1. 传统写法
function Point(x, y) {
  this.x = x;
  this.y = y;
}
Point.prototype.toString = function () {
  return "(" + this.x + ", " + this.y + ")";
};
let p = new Point(1, 2); // {x:1,y:2}

// 2. class 改写 =>
class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
    console.log("this->", this); // Point {x:1,y:2}
  }
  toString() {
    return "(" + this.x + ", " + this.y + ")";
  }
}

let p = new Point(1, 2); // {x:1,y:2}

// 等同于
Point.prototype = {
  constructor() {},
  toString() {},
};

typeof Point; // 'function'
Point === Point.prototype.constructor; // true

setter/getter

使用 get/set 关键字对某个属性设置 取值/存值函数,对该属性的操作进行拦截

class MyClass {
  constructor() {}
  get age() {
    return "get age";
  }
  set age(value) {
    console.log("setter: " + value);
  }
}
let inst = new MyClass();
inst.age= 123; // setter: 123
inst.age; // 'get age'

Class 的继承

子类的this 必须先完成构造父类的构造函数,则子类在构造器中必须先调用super方法,若子类不声明构造器,则会默认被加上

class Person{
  constructor(name, age) {
    this.name= name;
    this.age= age;
  }
}

class teacher extends Person{
	constructor(...args) {
    	super(...args);
 	}
}
class Person{
  constructor(name, age) {
    this.name= name;
    this.age= age;
  }
}

class Teacher extends Person{
  constructor(name, age, height) {
    this.height= height; // ReferenceError
    super(name, age);
    this.height= height; // 正确
  }
}

类的 prototype 和__proto__

Class 是构造函数的语法糖,同时有prototype属性和__proto__属性,同时存在两条继承链。

  • 子类的__proto__属性,表示构造函数的继承,总是指向父类。
  • 子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。
class A {
}

class B extends A {
}

B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true

实例的 proto

const p = new Person()
const tec = new Teacher()
tec.__proto__.__proto__ == p.__proto__   //true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值