原型链、隐式原型

原型链、隐式原型之间的关系你搞懂了吗?

听说面试要被考到?

原型和原型链

你们知道所有的对象都是通过new函数创建的吗?

var obj = new Object(); var obj = {}

这里的var obj={},大括号是语法糖 相当于new Object={};

在这里插入图片描述
就比如:

function test(){
  return {}
}

new test();--------这里是有产生对象的,并且这里的构造函数是Object对象,因为return返回的是一个{} 相当于return new Object;

所有的函数也是对象

Function函数也是一个对象,但是所有的对象都是通过new来创建的,所以Function是放在内存中的,js引擎启动的时候直接把Function放在内存中。

typeof Object-----“function”
typeof Array----“function”

函数里面可以有属性

Array.isArray();

所有对象都是引用类型(—保存的是地址 ,赋值的也是地址)

什么是原型?

JS中的对象包含了一个prototype的内部属性,这个属性所对应的就是该对象的原型。
我们先看下图:a、b、c 分别为数组、对象、函数。
var a =[1,2,3]
var b = {
color:‘red’,
size:‘12’
}

function c(){
alert(‘c’)
}

可以看到,三者都有一个属性:__proto__

这个 __proto__称作 隐式原型。
除此之外,c还有一个属性:prototype

这个prototype 称作 显式原型。

原型 prototype

所有函数都有一个属性:prototype,称之为函数原型
只要是函数都有原型

默认情况下,prototype是一个普通的Object对象
默认情况下,prototype中有一个属性,constructor,它也是一个对象,他指向构造函数本身。

这里强调的是默认情况下
在这里插入图片描述
test.prototype.constructor === test返回的是true

隐式原型 __proto__(两个下划线开头的一般都是系统变量,不要轻易改变)

(1)所有的对象都有一个属性:__proto__,称之为隐式原型
(2)在原型链中依次查找是否拥有该成员,如果有直接使用

({}).__proto__

var obj = {};
obj.prototype;----undefined

obj是一个普通对象,不是函数,就没有prototype,普通对象是有__proto__的

obj.__proto__ ={constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}

因为prototype也是一个对象,所以prototype也有__proto__
在这里插入图片描述

当访问一个对象的成员时:

  1. 看该对象自身是否拥有该成员,如果有直接使用
  2. 在原型链中依次查找是否拥有该成员,如果有直接使用

猴子补丁:在函数原型中加入成员,以增强起对象的功能,
猴子补丁会导致原型污染,使用需谨慎。



 function test1() {
    return {};//这里就相当于new Object()
}
var obj = new test1();
console.log(obj.__proto__ === test1.prototype); //输出false


function test2() {
    
}
var obj = new test2();
console.log(obj.__proto__ === test2.prototype); //输出true

所有的函数都是通过new Function来产生的

特殊点:
1.Function的__proto__指向自身的prototype
2.Object的prototype的__proto__指向null

在这里插入图片描述
在这里插入图片描述

   function User(){}
        User.prototype.sayHello = function(){}

        const u3 = new User();
        const u4 = new User();

        console.log(u3.sayHello === u4.sayHello);//true
        console.log(User.prototype.constructor);//User
        console.log(User.prototype === Function.prototype);//false
        console.log(User.__proto__ === Function.prototype );//true
        console.log(User.__proto__ === Function.__proto__);//true
        console.log(u3.__proto__ === u4.__proto__);//true
        console.log(u3.__proto__ === User.__proto__ );//false
        console.log(Function.__proto__===Object.__proto__);//true
        console.log(Function.prototype.__proto__ === Object.prototype.__proto__);//false
        console.log(Function.prototype.__proto__ === Object.prototype);//true

以上的代码照着上面的图做就可以做出来,以后做题就可以在脑海了会议这个图就很容易的写出来,面试的时候还会怕被问到原型和原型链吗?

小结一下:
所有引用类型(函数,数组,对象)都拥有__proto__属性(隐式原型)
所有函数除了有_proto_属性之外还拥有prototype属性(显式原型)
原型对象:每创建一个函数,该函数会自动带有一个prototype属性,该属性是一个指针,指向了一个对象,我们称之为原型对象。

总结如下:

  1. 实例对象a只有__proto__(隐式原型),构造函数既有 proto(隐式原型)也有prototype(显式原型)
  2. proto 和 prototype 都是一个对象,既然是对象,就表示他们也有一个 proto
var F = function () {}
Object.prototype.a = function () {}
Function.prototype.b = function () {}

var f = new F();

console.log(f.a, f.b, F.a, F.b);
// fn    undefined    fn    fn

// 看图,所有的Function原型都指向Object原型,所以所有对象的原型上都有a
//所有的函数都有b方法了,F是函数,f是通过函数创建的对象
 function A() {}
        A.prototype.toString = function() {
            return "123";
        }
        var obj = new A();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值