js不是随便一个对象就可以使用prototype吗?

比如
var a = [1,2,3];
a.prototype.b = function(){console.log(this)};
a.b();
这样写为什么是错的呢?

阅读 3.8k
6 个回答

函数(正常来说是构造函数)才有prototype

prototype是构造函数的属性,它指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。

你这里的a是实例而不是构造函数,要搞清楚面向对象这几个概念,看一下正确的写法,或许你就明白了

Array.prototype.b = function(){ console.log(this) }
var a = new Array(1,2,3) //或 var a = [1,2,3]
a.b() // [1,2,3]

建议看一下面向对象的相关知识

这个问题很有意思,不过首先要明确prototype到底是指什么。

  • 如果是指“原型”,则题目变为“每个对象都有原型,并且可以任意修改”这句话对吗?,
  • 但如果只是指“prototype这个属性”,即a.prototype存在吗,这是全部的答案在回答的。

如果题主是对第一种情况感兴趣,可以继续看下去。

每个对象都有原型吗?

每个对象都有原型,这句话对,也不对,Object.create(null)得到的对象没有原型,这一般是用来实现一个“纯净”的容器。

大部分情况下每个对象都有原型,当获取对象上的属性时,如果该对象上没有,就会去原型上寻找,这就是a.push(2)可以执行的原因,a没有push方法,但a的原型上有。

可以任意修改原型吗?

既然a是有原型的,那可以修改吗,可以的。如果是在chrome控制台可以简单实验下:

const a = [1, 2, 3];
a.__proto__.b = function () {console.log('b function ', this)};
a.b();

__proto__不是规范的,所以需要用Object.getPrototypeOf()拿到后再修改。

const ary = [1, 2, 3];
const aryPrototype = Object.getPrototypeOf(ary);
aryPrototype.b = function () {console.log('b function ', this)};
ary.b();

因为var a = []; == var a = new Array;

Array.prototype.b = function(){console.log(this)};

这样应该就可以了,因为 a作为 Array原型的实例。
如果要访问某对象a的原型,需要这样写

Object.getPrototypeOf(a)

或者

a.constructor.prototype 

如果a是构造函数,可以直接通过a.prototype访问,上面就是先调出a的构造函数

var a = [1, 2, 3];
Array.prototype.b = function(i) {
  alert(this[i]);
};
a.b(a.length - 1);
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题