JavaScript的原型链问题-Function与Object

本文探讨了JavaScript中对象的__proto__属性和Function.prototype的独特关系,解释了如何通过__proto__判断变量类型,以及内置函数如Array和String的原型处理。还涉及原型链的结构,如何使用Object.prototype.toString来确定变量类型,并展示了Function与其他对象如Object的交互方式和原型链终点。

只有函数对象身上会有prototype属性
只有是对象身上会有__proto__属性,即JS中所有变量或数据身上都有__proto__属性

不同对象的__proto__

不同变量即对象的__proto__,就是变量类型构造函数的prototype

1.0.__proto__===Number.prototype  //true
'a'.__proto__===String.prototype  //true
[].__proto__===Array.prototype;  //true
/a+/.__proto__===RegExp.prototype; //true
let obj ={};
obj.__proto__===Object.prototype;  //true

什么对象既有prototype又有__proto__

既有prototype又有__proto__,说明它既是对象,也是函数,但是JavaScript中所有变量都是对象,
所以总结来说,函数变量既有prototype又有__proto__

function f(){};
f.prototype;

函数的原型

f.__proto__;
ƒ () { [native code] }
可以通过全等验证f.__proto__是什么
f.__proto__===Function.prototype;  //true

Array,String等内置函数的prototype会有些不同,来实现类多态处理对应的数据类型。但是_proto__
都是一样的,即Function作为构造函数new而来,指向Function.prototype

Array.__proto__===Function.prototype;  //true
String.__proto__===Function.prototype;  //true

Function 与Object的关系

Object作为函数对象时,也可以看做Function的实例,如下:

Object.__proto__===Function.prototype;
true

Function既是对象又是自身的构造函数,所以他的__proto__与原型相同,如下:

Function.__proto__===Function.prototype;
true

为了避免Function原型链的循环,所以规定 Function的原型链指向Object的原型,如下:
Function.prototype作为一个对象,可视为Object的实例对象。

Function.prototype.__proto__===Object.prototype;
true

原型链的尽头

原型链的尽头就是Object.prototype

Object.prototype.prototype;  //undefined
Object.prototype.__proto__;  //null

Object.prototype.toString.call

如果想要判断任何变量/数据的准确,可以使用Object.prototype.toString的方式,将this指向要判断的变量。

Object.prototype.toString.call(0)
'[object Number]'
Object.prototype.toString.call({})
'[object Object]'
Object.prototype.toString.call([])
'[object Array]'
Object.prototype.toString.call('str')
'[object String]'

使用原型链终点上的toString的原因是:其他原型对象身上继承的toString会进行一定改写来更符合某一指定数据类型。如:

Number.prototype.toString.call(0)
'0'
Number.prototype.toString.call('1')
VM2546:1 Uncaught TypeError: Number.prototype.toString requires that 'this' be a Number
    at String.toString (<anonymous>)
    at <anonymous>:1:27

注:toString方法一般是在原型对象身上,通过原型链访问

//(Object.__proto__ === Function.prototype).toString
Object.toString.call({name:1})
Uncaught TypeError: **Function.prototype**.toString requires that 'this' be a Function
    at Object.toString (<anonymous>)
    at <anonymous>:1:17
 
//(Number.__proto__ === Function.prototype).toString 
Number.toString.call(1);
Uncaught TypeError: Function.prototype.toString requires that 'this' be a Function
    at Number.toString (<anonymous>)
    at <anonymous>:1:17

//(str.__proto__ === String.prototype).toString
'1'.toString.call(1);
Uncaught TypeError: String.prototype.toString requires that 'this' be a String
    at Number.toString (<anonymous>)
    at <anonymous>:1:14

Object.prototype.toString通过对象的symbol.toStringTag获取类型,可以手动改变其值:

const myDate = new Date();
Object.prototype.toString.call(myDate); // [object Date]

myDate[Symbol.toStringTag] = "myDate";
Object.prototype.toString.call(myDate); // [object myDate]

Date.prototype[Symbol.toStringTag] = "prototype polluted";
Object.prototype.toString.call(new Date()); // [object prototype polluted]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晨灰ash2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值