【JS】原型链

540 阅读3分钟

函数对象有prototype显式原型属性 实例对象有__proto__隐式原型属性

例如新建的html中,并没有进行创建Object的实例对象,但是自带有Object函数对象,则此对象有 prototype显式原型属性。Object.prototype与Object的实例对象的__proto__属性相等,可用===进行判断,返回true;

	//新建一个Function(){}函数对象
	function Fn(){
		console.log("我是Fn");
	};
	//构造一个Function的实例对象fn
	var fn = new Fn();
	//此时Fn.prototype === fn.__proto__
	console.log(Fn.prototype === fn.__proto__);//返回true
	

Fn的原型指向的是一个空的Object对象,既然是称为空的Object对象,而不是Object函数,所以是一个Object 的实例对象,由系统自己创建的,文章开头说了系统有内置的Object函数对象,所以此时的空Object对象的__proto__隐式原型属性与内置的Object函数对象的prototype显式原型属性相等

	//新建一个Function(){}函数对象
	function Fn(){
		console.log("我是Fn");
	};
	//构造一个Function的实例对象fn
	var fn = new Fn();
	//此时Fn.prototype === fn.__proto__
	console.log(Fn.prototype === fn.__proto__);//返回true

	//Fn.prototype.__proto__ === Object.prototype
	console.log(Fn.prototype.__proto__ === Object.prototype);//依然返回true

    //Fn.prototype.__proto__ 与 Object.prototype都共同指向原型链的终点,
    //即为Object的原型对象,它是一个实例对象,所以也拥有__proto__属性,但该属性值为null

一个函数的属性,会先在函数本身里面寻找,没有的话就顺着原型链到原型对象中寻找,再没有,便去Object的原型对象中找,每个函数对象的原型对象(Object空对象)中的属性或许不同,但再往上就都是Object的原型对象,其中定义了toString等方法,这也是为什么一来就能用这些方法的原因。 如果都没有找到该属性,则返回undefined (目前存在疑问1、既然最终都共用原型链终点,那在一个函数中修改其中的值,会影响其他的吗,比如toString,理论上感觉是可以的)

b站尚硅谷课程截图 在这里插入图片描述 进阶 构造函数可以写成 function Xxx(){ };可以写成 var Xxx = function(){ },也可以写成var Xxx = new Function() 所以任何函数都可以看做是Function构造函数的一个实例对象那么必然有Xxx.__proto__的属性指向Function.prototype new Function()的基本用法:最后一个参数是函数的 body(函数体),类型为 string;

	// 最后一个参数是函数的 body(函数体),类型为 string;
	// 前面的参数都是 索要构造的函数的参数(名字)
	var myFunction = new Function('users', 'salary', 'return users * salary');

function Xxx(){ }为例

	function Fx(){
        console.log('1')
    }
    // var Fx = function(){
    //     console.log("2")
    // }
    // var Fx = new Function("console.log('3')");
    Fx();//返回1

var Xxx = function(){ }为例

	// function Fx(){
    //     console.log('1')
    // }
    var Fx = function(){
        console.log("2")
    }
    // var Fx = new Function("console.log('3')");
    Fx();//返回2

var Xxx = new Function()为例

    // function Fx(){
    //     console.log('1')
    // }
    // var Fx = function(){
    //     console.log("2")
    // }
    var Fx = new Function("console.log('3')");
    Fx();//返回3

三种创建函数的办法,殊途同归,可知当系统内置Object函数的时候必然会使用其中一种,此时为了便于理解,以第三种方法为其构造办法那么有var Object = new Function();得知Object函数为Function的一个实例对象,则作为实例对象,Object应该有__proto__隐式原型属性,指向Function的显式原型Function.prototype,同时,它还是Object函数对象,对应这有prototype显式原型属性。

同理Function函数同样也可以理解为var Function = new Function()出来的,实例对象的隐式原型等于构造函数的显式原型,因此Function是实例对象也是构造对象,Function的__proto__隐式原型属性指向Function.prototype,反过来也成立。 在这里插入图片描述 所以函数都是new Function产生的,所以所有函数的隐式原型都是一样的,__proto__都一样,都为Function.prorotype 在这里插入图片描述