扫码关注官方订阅号
Function和Function.prototype都有call(),为什么有Object.call(),而Object.prototype没有call()? 还有freeze()等等
Function
Function.prototype
call()
Object.call()
Object.prototype
freeze()
走同样的路,发现不同的人生
因为call这个方法是挂载到Function的原型上的, 而所有的 函数 都是由 Function 创造出来的
所以
Function 是由 Function 创造出来的 它是Function的实例 他能调用 Function 原型上的方法
Function.prototype 就不用说了,本来就是他自己的方法
Object 是由 Function 创造出来的的 ...
Object.prototype 不是函数
在计算机语言里,int a;定义了一个int类型的变量a。其中int是类型的名字,a是具体的变量。
int a;
int
a
Javascript 模仿自 Java, 有一部分面向对象编程的部分。在面向对象的编程中,类就是像int那样是类型,对象就是具体的变量。比如:
class Point { constructor(x,y){ //构造函数 this.x=x;this.y=y; // 其中的this 就是创建出来的新对象 } toString(){ return "(" + this.x +"," + this.y + ")";} }; // 这样就创建了一个叫做`Point`的类, var p = new Point(1,2); // 调用构造函数生成一个Point类的对象 // 或者说 Point p = new Point(1,2); // 即定义了一Point类型的变量 p,赋值为某个值。 p.toString();// "(1,2)" p.x; // 1
可是 Javascript 是若类型,写出了Point类型又有什么意义呢,又不能写Point p = xx。于是在JS里面把类型和函数合二为一。当定义了一个函数,那么这个变量名称既是一个函数也是一个类型的名称,并且这个函数是这个类型的构造函数(也是一个普通的函数)。这样做不会出现歧义,因为没有Point p这种写法,所以除了p instanceof Point之外,Point在JS里面永远指一个函数。
Point
Point p = xx
Point p
p instanceof Point
下面要解决的是,Point类型里面的toString函数。如果
toString
functioin Point(x,y) { // Point类的构造函数,即上面的 constructor this.x = x; this.y=y; this.toString = function() { return "(" + this.x +"," + this.y + ")";} } var p1 = new Point(1,2); var p2 = new Point(3,4); p1.toString === p2.toString; // False
这样定义Point类是可行的,可是却存在着问题。可以看出方法toString其实是定义了两个不同的函数,其代码是一样的。也就是说toString函数在内存中创建了两次,而且代码相同,这样是一种浪费。(由于属性x在p1和p2中保存不同的值,所以创建两个是必须的,可是toString不一样)
x
p1
p2
下面是一种解决方法:
var PointMethod = { // 把所有方法放到一个额外的对象中 toString: function() { return "(" + this.x +"," + this.y + ")";} toValue: function() { return [this.x,this.y];} } functioin Point(x,y) { this.x = x; this.y=y; this.__method__ = PointMethod; } var p1 = new Point(1,2); var p2 = new Point(3,4); //当我们要访问一个方法时 p1.__method__.toString(); // 先不考虑this的问题 p1.__method__.toString === p2.__method__.toString; // true
这样有点儿麻烦,所幸的是JS解释器帮我们做了一些东西,让我们方便的写出和上面工作原理一样的如下代码。
function Point(x,y){ this.x = x; this.y = y; // 当使用 new Point 的时候自动添加如下代码 // this.__proto__ = Point.pototype; } Point.prototype = { // PointMethod toString: function() { return "(" + this.x +"," + this.y + ")";} toValue: function() { return [this.x,this.y];} } var p1 = new Point(1,2); var p2 = new Point(3,4); p1.toString(); // 即 p1.toString? p1.toString:p1.__proto__.toString ... p1.toString == p2.toString; // true;
由于Object是类型名称,所以他也是函数。Object是函数,所以他是Function类的变量,而所有Function类的变量(函数)都可以被调用,有call方法。所有函数类型的方法都在Function.prototype中,所以有Function.prototype.call。故此Object.call是可以的,其实就是Object.__proto__.call。
Object
call
Function.prototype.call
Object.call
Object.__proto__.call
Function是类型名称,所以也是函数,所以Function是Function类型的变量。(上面说过,函数名可以和类型名重名,或者说故意让他们重名,而不会在代码里有歧义)所以有Function.call其实也是 Function.__proto__.call。
Function.call
Function.__proto__.call
所有对象都是Object类型的(忽略继承先),Object类变量的方法都在Object.prototype中,可是不是所有的对象都能想函数那样被调用,所以不能有call。
Object instanceof Function; // true Object.__proto__ === Function.prototype; // true Function.__proto__ === Function.prototype; // true var obj = {}; // 等价于 var obj = new Object(); obj.__proto__ === Object.prototype; // true;
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
因为call这个方法是挂载到Function的原型上的, 而所有的 函数 都是由 Function 创造出来的
所以
Function 是由 Function 创造出来的 它是Function的实例 他能调用 Function 原型上的方法
Function.prototype 就不用说了,本来就是他自己的方法
Object 是由 Function 创造出来的的 ...
Object.prototype 不是函数
在计算机语言里,
int a;定义了一个int类型的变量a。其中int是类型的名字,a是具体的变量。Javascript 模仿自 Java, 有一部分面向对象编程的部分。在面向对象的编程中,类就是像
int那样是类型,对象就是具体的变量。比如:可是 Javascript 是若类型,写出了
Point类型又有什么意义呢,又不能写Point p = xx。于是在JS里面把类型和函数合二为一。当定义了一个函数,那么这个变量名称既是一个函数也是一个类型的名称,并且这个函数是这个类型的构造函数(也是一个普通的函数)。这样做不会出现歧义,因为没有Point p这种写法,所以除了p instanceof Point之外,Point在JS里面永远指一个函数。下面要解决的是,
Point类型里面的toString函数。如果这样定义
Point类是可行的,可是却存在着问题。可以看出方法toString其实是定义了两个不同的函数,其代码是一样的。也就是说toString函数在内存中创建了两次,而且代码相同,这样是一种浪费。(由于属性x在p1和p2中保存不同的值,所以创建两个是必须的,可是toString不一样)下面是一种解决方法:
这样有点儿麻烦,所幸的是JS解释器帮我们做了一些东西,让我们方便的写出和上面工作原理一样的如下代码。
由于
Object是类型名称,所以他也是函数。Object是函数,所以他是Function类的变量,而所有Function类的变量(函数)都可以被调用,有call方法。所有函数类型的方法都在Function.prototype中,所以有Function.prototype.call。故此Object.call是可以的,其实就是Object.__proto__.call。Function是类型名称,所以也是函数,所以Function是Function类型的变量。(上面说过,函数名可以和类型名重名,或者说故意让他们重名,而不会在代码里有歧义)所以有Function.call其实也是Function.__proto__.call。所有对象都是
Object类型的(忽略继承先),Object类变量的方法都在Object.prototype中,可是不是所有的对象都能想函数那样被调用,所以不能有call。