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

被折叠的 条评论
为什么被折叠?



