原型和原型链


如果内容理解有误,请友友们不吝纠正

8,原型和原型链

  • 1,每个函数都有一个prototype,即显示原型。默认指向一个空的Object对象。【但是Object函数的显示原型不指向空对象而是null
  • 2,每个实例对象都有一个__proto__,隐式原型。【左右分别是两条下划线】
  • 3,【实例对象的隐式原型的值为其对应的构造函数的显示原型的值】。【即Fn.prototype === fn.__proto__
  • 4,开发者可以直接操作显示原型,【ES6之前】不能直接操作隐式原型。
function Fn() {}

console.log(Fn.prototype);
var fn = new Fn();
console.log(fn.__proto__);
console.log(Fn.prototype === fn.__proto__);//true

在这里插入图片描述

8.1,原型

prototype :给一类对象设置公用的属性或方法。原型就是一个技术栈。比如Array数组的所有方法,字符串的所有方法等都属于原型。原型上的方法是给实例对象使用的。

补充:


		var a = "foo";
        var b = new String("foo");
        var c = String("foo");
        console.log(a == b);  //值相等就行 true
        console.log(a.repeat);
        console.log(typeof a);//string
        console.log(typeof b);//object
        console.log(typeof c);//string
        console.log(a.repeat === b.repeat); //true
        console.log(a === b); //一个string,一个object,false
        console.log(a === c); //true
        
	var a = '77';   //  a有原型吗?   无
	var b = String('77');  // b有原型吗?无   a和b都属于基本数据类型。12,[2,4] ,true ,false ,{}等,都属于js直接量,都没有原型。原型是一个技术栈。
	var c = new String('77');   // c有原型吗?  c有__proto__ , c没有prototype  
	
	通过String直接创建的字符串和字符串表面量为基本数据类型,属于JavaScript中的直接量(包含数字,以及数组、对象和正则表达式、数字和布尔值的直接量格式)。

	通过 New String来实例化的是一个String对象, 所以可以调用String对象的方法。

8.2,原型链–本质上是隐式原型链

_proto_: 所有数据类型都属于对象,对象的所有公用属性和方法在所有数据类型中都可以使用。即所有数据类型都链Object。

  • 当通过对象访问对象的属性时,先在自身属性中寻找,找到并返回。
  • 如果没有找到,会沿着隐式原型__proto__这条链向上查找,找到并返回。
  • 若没有找到,返回undefined。表示属性已声明但并未赋值。

原型链的作用:查找对象的属性。
延申:作用域链的作用–查找变量。
在这里插入图片描述

  • 构造函数/原型/实例对象的关系图解1:
    在这里插入图片描述

  • 构造函数/原型/实例对象的关系图解2:
    所有函数的__proto__都指向Function的显示原型prototype。因为类似Object函数都是通过 var Object = new Function() 定义的。而实例对象的隐式原型 === 构造函数的显示原型。
    在这里插入图片描述

8.3 原型继承:通过原型链

  • 构造函数的实例对象自动拥有/继承构造函数原型对象的属性和方法。【方法也是一种特别的属性。本篇文章中我将属性和方法统称为属性。】

8.4 原型链的补充:

  • 每个函数都有一个prototype,即显示原型。默认指向一个空的Object对象。【但是Object函数的显示原型不指向空对象而是null,是个例外】;
  • 所有函数都是Function的实例。Function 是它自身的实例。即所有函数都是Function的实例,包括它本身;
  • Object的原型对象是原型链的尽头。【因为Object.prototype.__proto__为null。】
console.log(Fn.prototype instanceof Object);//true
console.log(Function.prototype instanceof Object);//true

console.log(Object.prototype instanceof Object);//false

console.log(Function.__proto__ === Function.prototype);//true

console.log(Object.prototype.__proto__);//null

原型链的属性问题:

  • 原型链是用来查找对象属性的。读取对象的属性值时,会自动到原型链中查找;
  • 设置对象的属性时,不会去查找原型链。如果当前对象中没有此属性,会直接添加此属性并赋值;
  • 方法一般定义在原型中,属性一般通过构造函数定义在对象本身上。
function Fn() {

};
Fn.prototype.a = 'xxx';

var fn1 = new Fn();
console.log(fn1.a);//xxx   读取值会先去查找对象本身,对象没有会自动到原型链去查找。就找到了原型链上的a
var fn2 = new Fn();
fn2.a = 'yyy';//设置对象属性不会去查找原型链。而是查找对象,fn2并没有a属性,就会直接添加属性并设置值。

console.log(fn1.a, fn2.a, fn2);//xxx   yyy   Fn{a:'yyy',__proto--:{ a:'xxx'}  }

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

console.log(p1);// name:'Bob',age:12,__proto__
console.log(p2);//name:'Cat',age:12,__proto__

8.5 探索instanceof:

  • 使用方法: a instanceof A a代表实例对象,A代表函数。

  • 判断依据: A函数的显示原型对象如果在a对象的隐式原型链上,返回true。
    在这里插入图片描述
    对于:
    Function instanceof Object 以及 Object instanceof Function的理解:
    在这里插入图片描述
    对于Object instanceof Object 和 Function instanceof Function的理解:
    在这里插入图片描述

     总结一下:
     所有函数的显示原型对象都默认指向一个空的Object对象【Object函数除外】。
     原型链的尽头是Object的隐式原型对象。对象的隐式原型对象恒等于函数的显示原型对象。
     所有函数都是Function的实例,包括它本身。
    

关系图理解:
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值