JavaScript 原型与继承机制详解(5)

1 if (!String.prototype.trim) { 2 String.prototype.trim = function() { 3 return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); 4 }; 5 }

  不过需要注意,切忌随意修改内置对象的原型方法,一是因为这会带来额外的内存消耗,二是这可能会在系统中造成一些隐患,一般只是用来做浏览器兼容的 polyfill 。

四、 有关原型的方法

   for ... in 语句会遍历原型链上所有可枚举的属性(关于属性的可枚举性质,可以参考 《JavaScript 常量定义》),有时我们在操作的时候需要忽略掉原型链上的属性,只访问该对象上的属性,这时候我们可以使用 Object.prototype.hasOwnProperty() 方法来判断属性是否属于原型属性:

1 var obj1 = { 2 x:1, 3 } 4 5 var obj2 = { 6 y:2, 7 __proto__:obj1 8 } 9 10 for(var key in obj2){ 11 console.log(obj2[key]); //2, 1 12 } 13 14 for(var key in obj2){ 15 if(obj2.hasOwnProperty(key)){ 16 console.log(obj2[key]); //2 17 } 18 }

  我们知道通过 new 操作符创建的对象可以通过 instanceof 关键字来查看对象的“类”:

1 function foo () {} 2 3 var obj = new foo(); 4 5 console.log(obj instanceof foo); //true

  实际上这个操作也是不严谨的,我们现在已经知道了 new 操作符在 JavaScript 当中本是一个具有歧义设计,instanceof 操作符本身也是一个会让人误解的操作符,它并没有实例这种说法,实际上这个操作符只是判断了对象与函数原型的关联性,也就是说其返回的是表达式 object.__proto__ === function.prototype 的值。

1 function foo () {}
2
3 var bar = {
4    x:1
5 }
6
7 foo.prototype = bar
8
9 var obj = {
10     __proto__: bar
11 }
12
13 console.log(obj instanceof foo);  //true

  在这一段代码中,我们可以看出 obj 和 foo 并没有任何关系,只是 obj 的原型和 foo.prototype 关联到了同一个对象上面,所以其结果会返回 true。  

  不过对基本类型类型使用 instanceof 方法的话,可能会产生意外的结果:

1 console.log("1" instanceof String); //false 2 3 console.log(1 instanceof Number); //false 4 5 console.log(true instanceof Boolean); //false

  但是我们同样可以使用使用字面量调用原型的方法,这可能会让人感到困惑,不过我们不用担心它,并不是原型链出现什么毛病,而是在对基本类型进行字面量操作的时候,会涉及到隐式转换的问题。JS 引擎会先将字面量转换成内置对象,然后在调用上面的方法,隐式转换问题不在本文的讨论范围之类,大家可以参考 Kyle Simpson — 《你不知道的 JavaScript (中卷)》。

  实际对象的 Object.prototype.isPrototypeOf() 方法更能体现出对象原型链的关系,此方法判断一个对象是否是另一个对象的原型,不同于 instanceof 的是,此方法会遍历原型链上所有的节点,若有匹配项则返回 true:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/9fffa9f22ed89d78b1b09dc5ec45d6c5.html