js原型链以及手写new方法

//原型链
//通过new 函数名来实例化对象的函数叫做构造函数
//构造函数的主要功能为初始化对象,特点是和new一起使用 构造函数定义时首字母大写 为初始化的对象添加属性和方法

function Person(name) {
    this.name = name
}
let person = new Person('张三'); //person为一个新对象
console.log(person.name);

//new一个新对象的过程
//1.创建一个空对象
//2.空对象的_proto_指向构造函数的prototype成员对象
//3.使用apply调用构造器函数,属性和方法被添加到this引用的对象中
//4.如果构造函数中没有返回其他对象,那么返回this,即创建的这个新的对象,否则返回构造器函数中返回的对象

//手写new 函数
function _new(func, ...args) {
    let obj = {};
    obj.__proto__ = func.prototype; // 一二步合并就相当于 let obj = Object.create(func.prototype)
    let result = func.apply(obj, args);
    return typeof result === 'object' ? result : obj;
}
let person2 = _new(Person, '李四');
console.log(person2.name);
//new申请内存,创建对象,当调用new时,后台会隐式执行new Object() 创建对象,所以当用new创建的字符串,数字是引用类型,而非值类型


//原型的作用是共享方法,不会反复开辟内存空间,减少内存浪费。this指向实例化对象
//函数对象分为三种
//1.__proto__ 任何对象中都有__proto__属性(隐式原型)
//2.prototype 所有函数(仅限函数)都拥有prototype属性
//3.constructor 所有的prototype和实例化对象都有constructor属性,都指向关联的构造函数本身

function Hello() {

}
let hello = new Hello()
console.log(Hello.prototype); //对应2 true
console.log(Hello.prototype.constructor === Hello)//对应3 true
console.log(hello.prototype);//undefined 只有函数有prototype属性,实例化对象没有

console.log(hello.__proto__ === Hello.prototype)
console.log(hello.__proto__ === hello.constructor.prototype)
console.log(hello.constructor.prototype === Hello.prototype)
console.log(hello.constructor === Hello); //对应3

//实例化对象 有1,3实例化对象的3有2 ;函数有2 函数的2有3 实例化对象的__proto__等于函数的prototype 实例化对象的constructor等于函数自身
//函数的2的3 等于函数自身


//prototype
//所有函数(仅限函数)拥有prototype属性
//prototype 对象用于放某同一类型实例的共享属性和方法,实际上为了节省内存
Person.prototype.sayHello = function () {
    console.log(this.name + 'hello')
}
let person1 = new Person('张三');
let person3 = new Person('李四');
console.log('prototype', person1.sayHello === person3.sayHello)

//__proto__
//所有对象都拥有__proto__属性
//__proto__指向分为三种情况
//字面量模式
var a = {};
console.log(a.constructor === Object);
console.log(a.constructor.prototype === Object.prototype);
console.log(a.__proto__ === Object.prototype);
console.log(a.__proto__ === a.constructor.prototype);

//构造器方式
var B = function () { };
var b = new B();
console.log(b.constructor === B);
console.log(b.__proto__ === B.prototype)

//Object.create()方式


//constructor 指向创建该对象的构造函数
//每个原型对象都可以通过对象.constructor指向创建该对象的构造函数
function ConstructorPerson() { }

let constructorPerson1 = new ConstructorPerson();
let constructorPerson2 = new ConstructorPerson();

constructorPerson1.constructor == ConstructorPerson;
ConstructorPerson.prototype.constructor = ConstructorPerson;
//由此得
constructorPerson1.constructor = ConstructorPerson.prototype.constructor;
constructorPerson1.__proto__ = ConstructorPerson.prototype;


//原型链
//由于__proto__是任何对象都有的属性,而js李万物皆对象,所以会形成一条__proto__连起来的
//链条,递归访问__proto__必须最终到头,并且值是null
//当js引擎查找对象的属性时,先查找对象本身是否存在该属性,如果不存在,会在原型链中查找,但不会查找自身的prototype
var C = function () { }
var c = new C();

c.__proto__ === C.prototype;
C.prototype.__proto__ === Object.prototype;
Object.prototype.__proto__ === null;


//instanceof原理
//instanceof只能用来判断对象类型,原始类型不可以(可以用typeOf) 并且所有对象类型 instanceof Object 永远为true
//instanceof的内部机制是通过判断对象的原型链中是不是能找到类型的prototype
class People { };
class Student extends People { }
let s1 = new Student();

console.log(s1 instanceof Student);
console.log(s1 instanceof People);
console.log(s1 instanceof Object);

console.log(s1.__proto__  === Student.prototype);
console.log(Student.prototype.__proto__ === People.prototype);
console.log(People.prototype.__proto__ === Object.prototype);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值