`
风雪涟漪
  • 浏览: 506985 次
  • 性别: Icon_minigender_1
  • 来自: 大连->北京
博客专栏
952ab666-b589-3ca9-8be6-3772bb8d36d4
搜索引擎基础(Search...
浏览量:9009
Ae468720-c1b2-3218-bad0-65e2f3d5477e
SEO策略
浏览量:18386
社区版块
存档分类
最新评论

Javascript Prototype (二)

阅读更多

穷举属性(Enumerating Properties)

要列出对象所有的属性可以用for.in循环来做

var o = {p1: 1, p2: 2};
for (var i in o) {
  console.log(i + '=' + o[i]);
}

 结果为:p1=1,p2=2

 

但是有以下几点需要注意

  • 并不能把对象的所有属性列出来。像constructor属性就没有。可以列出的属性我们叫它可以枚举的(enumerable),可以用propertyIsEnumerable()方法来判断属性是否可以列出来。
  • 可以把prototype的属性列出来,如果要判断对象的自身属性可以用hasOwnProperty() 方法
  • 虽然可以列出所有prototype的属性,但是如果使用propertyIsEnumerable()方法来校验prototype的属性,它的返回结果都是false.

让我们看个综合例子就明白了

function Gadget(name, color) {
  this.name = name;
  this.color = color;
  this.someMethod = function(){return 1;}
}
Gadget.prototype.price = 100;
Gadget.prototype.rating = 3;

 创建一个新的对象

var newtoy = new Gadget('webcam','black');
for (var prop in newtoy) { 
  console.log(prop + ' = ' + newtoy[prop]); 
}

 结果为

   name = webcam
   color = black
   someMethod = function () { return 1; }
   price = 100
   rating = 3

 如果要区分自身属性和prototype属性,那就用hasOwnProperty()方法

 

for (var prop in newtoy) { 
  if (newtoy.hasOwnProperty(prop)) {
    console.log(prop + '=' + newtoy[prop]); 
  }
}

 结果为

  name=webcam
  color=black
  someMethod=function () { return 1; }

 再来看一下propertyIsEnumerable的方法

newtoy.propertyIsEnumerable('name');//true

 大部分内置的属性和方法都是不可以列举的

newtoy.propertyIsEnumerable('constructor');//false

 任何的属性来自prototype的都不能被列举

 newtoy.propertyIsEnumerable('price');//false

 如果进入prototype内部去调用属性就可以被列举了

 newtoy.constructor.prototype.propertyIsEnumerable('price');//true

 

扩展内置对象

内置对象就是由构造函数Array,String,Object。函数可以扩展它们的prototype,也就意味着你可以通过prototype添加Array的功能。

Array.prototype.inArray = function(needle) {
  for (var i = 0, len = this.length; i < len; i++) {
    if (this[i] === needle) {
      return true;
    }
  }
  return false;
}

 现在所有的Array都有了新的方法。

var a = ['red', 'green', 'blue'];
a.inArray('red');//true
a.inArray('yellow');//false

 通过prototype扩展Array的功能真是很简单的事情。

 

关于扩展内置对象的讨论

Prototype库是个比较有名的javascript库,它通过这种方法,把javascript变成了类似ruby的语言。但是YUI却反对这种做法。如果你会使用Javascript,一般希望用javascript正常的写法,改变了核心方法,会对开发人员造成许多困惑。

现在的javascript和浏览器功能都逐渐的增多,本身开发人员对Javascript核心的扩展,很可能明天就会没什么用处了。最佳实践是先判断核心的功能是否存在,然后再去扩展。如:

if (!String.prototype.reverse) {
  String.prototype.reverse = function() {   
    return Array.prototype.reverse.apply(this.split('')).join(''); 
  } 
}

 关于prototype令人迷惑的地方

function Dog(){
    this.tail=true;
}
var benji = new Dog();
var rusty = new Dog();
Dog.prototype.say = function(){
    return 'Woof';
}
benji.say();//Woof 
rusty.say();//Woof
benji.constructor;//Dog()
rusty.constructor;//Dog()
benji.constructor.prototype.constructor;//Dog()
typeof benji.constructor.prototype.tail;//undefined

Dog.prototype={paws:4,hair:true};
//Dog.prototype.constructor = Dog;
typeof benji.paws;//undefined
alert(benji.say());//Woof

var lucy = new Dog();//new object
alert(lucy.paws);
alert(lucy.tail)

lucy.constructor;//Object();
benji.constructor;//Dog():

typeof lucy.constructor.prototype.paws;//undefined
typeof benji.constructor.prototype.paws;//number

新建一个构造函数并创建两个对象

function Dog(){
    this.tail=true;
}
var benji = new Dog();
var rusty = new Dog();

建完对象之后,我们仍然可以添加属性到prototype中,对象可以访问这个新添加的属性

Dog.prototype.say = function(){
    return 'Woof';
}
benji.say();//Woof 
rusty.say();//Woof

 让我们来看看创建对象的构造函数,一起看来很正常

benji.constructor;//Dog()
rusty.constructor;//Dog()

 看如下代码很有意思的事情发生了。。。。。

benji.constructor.prototype.constructor;//Dog()

当我们想知道prototype的构造函数是啥的时候,问题出现了。。。结果是Dog()。但是这不完全正确。prototype对象仅仅是个Object对象,他并没有任何关于Dog的属性。。。测试看看

typeof benji.constructor.prototype.tail;//undefined

让我们继续深入下去。当完全重写prototype对象时看看会怎么样。

Dog.prototype={paws:4,hair:true};

发现了以前创造的对象竟然访问不了新的prototype的属性。。。

typeof benji.paws;//undefined
benji.say();//Woof

说明了旧的对象还是指向以前的Prototype了。

让我们新建一个对象看看会怎样

var lucy = new Dog();//new object
lucy.say();//TypeError:lucy.say is not a function
lucy.paws;//4

说明新建的对象已经指向新的prototype了。

但是lucy这个对象的构造函数变成了object

lucy.constructor;//Object();
benji.constructor;//Dog():

最令人感到困扰的是prototype的属性

typeof lucy.constructor.prototype.paws;//undefined
typeof benji.constructor.prototype.paws;//number

所以如果想完全重写prototype属性,建议用以下的方式。

Dog.prototype={paws:4,hair:true};
Dog.prototype.constructor=Dog;

 这样就不会造成以上的困扰了。。。。

 

3
0
分享到:
评论
3 楼 yujintao529 2013-06-04  
   
2 楼 cwqcwqmax9 2012-12-20  
建议 楼主 看看 这片文章就明白了  http://www.iteye.com/topic/1117700

1 楼 wuwenjie0506 2010-03-24  
谢谢楼主,再firebug下面调试一下就很清楚了.

相关推荐

    JavaScript的prototype

    JavaScript中的`prototype`是一个核心概念,它涉及到对象继承和函数原型。在JavaScript中,每创建一个函数,该函数就会自动获得一个名为`prototype`的属性,这个属性是一个对象,用于实现对象间的继承。同时,每个...

    javascript类库prototype.js

    Prototype.js 是一个强大的JavaScript类库,它为开发者提供了丰富的功能,使得创建具有高度互动性和Web2.0特性的富客户端页面变得更为简单。这个库的设计理念是扩展JavaScript的基础对象,提供一套统一且易于使用的...

    Advanced JavaScript (closures,prototype,inheritance)

    JavaScript,作为一种广泛应用于Web开发的脚本语言,其高级特性如闭包(closures)、原型(prototype)和继承(inheritance)是理解其精髓的关键。本文将深入探讨这些概念,帮助开发者更好地掌握JavaScript的核心。 ...

    javascript prototype文档.rar

    JavaScript中的原型(Prototype)是理解JavaScript继承机制的关键概念。它是一种对象属性,允许一个对象访问并继承另一个对象的属性和方法。在这个“javascript prototype文档”中,我们可以期待深入学习JavaScript...

    JavaScript_Prototype(源代码+中文手册).rar

    JavaScript Prototype 是一种重要的编程概念,尤其在Web开发中不可或缺。这个压缩包文件“JavaScript_Prototype(源代码+中文手册).rar”包含了关于JavaScript原型的源代码和中文手册,为学习和理解这一主题提供了...

    Prototype

    ### 二、Prototype 使用示例 1. **DOM操作示例**: ```javascript var element = $('myElement'); // 获取id为myElement的元素 element.insert('&lt;p&gt;Hello, World!&lt;/p&gt;'); // 在元素内插入文本 ``` 2. **AJAX...

    javascript prototype原型操作笔记.docx

    ### JavaScript Prototype原型操作知识点 #### 一、Prototype基础概念 **Prototype** 在 JavaScript 中是一个非常重要的概念,它支持面向对象编程中的继承特性。每个 JavaScript 对象都有一个内部属性 `[...

    javascript Prototype 对象扩展.docx

    #### 二、基本概念:使用`prototype`定义方法 在JavaScript中,通常情况下,当我们创建一个新对象时,会为该对象复制一份其构造函数中的方法。这种方法虽然简单直观,但在创建大量对象时会导致内存浪费,特别是在...

    Prototype_1.6 JavaScript代码和中文帮助手册

     prototype.js是一个非常优雅的javascript基础类库,对javascript做了大量的扩展,而且很好的支持Ajax,国外有多个基于此类库实现的效果库,也做得很棒。  prototype.js不仅是一个有很大实用价值的js库,而且有很...

    Professional JavaScript Frameworks: Prototype,YUI, ExtJS, Dojo and MooTools

    《Professional JavaScript Frameworks: Prototype,YUI, ExtJS, Dojo and MooTools》是关于JavaScript框架的高级编程资源,包含了各种知名框架的源代码,这些框架包括Prototype、YUI(Yahoo! User Interface Library...

    JavaScriptprototype的深度探索不是原型继承那么简单.pdf

    JavaScriptprototype的深度探索不是原型继承那么简单.pdf

    JavaScript prototype属性详解

    JavaScript中的`prototype`属性是面向对象编程的关键特性之一,它关联了函数(特别是构造函数)与实例之间的继承关系。每个函数都有一个`prototype`属性,这个属性是一个对象,包含了所有实例共享的方法和属性。当...

    了解JavaScript中的prototype (实例)

    JavaScript中的`prototype`是理解面向对象编程的关键概念之一。它是一种机制,允许对象共享属性和方法,从而实现代码复用。在JavaScript中,每个函数(包括构造函数)都有一个内置的`prototype`属性,这个属性指向一...

    javascript prototype原型详解(比较基础)

    javascript的prototype原型简单介绍: prototype原型是javascript中特别重要的概念,属于必须要掌握,如果没有良好的掌握的话,进一步用好或者学好js基本是不可能的实现的事情,并且此概念稍有难度,可能对于初次接触...

    jQuery、Mootools、Prototype三大JavaScript框架中文手册

    然而,原生JavaScript的API庞大且不统一,为了简化开发,社区创造了一系列的框架,其中jQuery、MooTools和Prototype是三个非常著名的JavaScript库。这些框架提供了一致的接口,增强了DOM操作,简化了事件处理,并...

    prototype.js javaScript插件

    **JavaScript原型(Prototype)库详解** JavaScript是一种动态类型的编程语言,其灵活性和强大的对象操作能力使其在Web开发中占据重要地位。"Prototype.js"是一个针对JavaScript的开源库,旨在增强和扩展JavaScript的...

    JavaScript使用prototype定义对象类型

    二、使用 Prototype 定义对象类型 使用 prototype 来定义对象类型非常简单,只需要创建一个对象,并将其 prototype 属性指向一个对象,该对象包含了该对象类型的所有方法和属性。例如,我们可以创建一个 Person ...

    javascript的prototype继承

    在JavaScript中,每个函数都有一个`prototype`属性,这个属性是一个对象,它的作用是当试图访问一个对象的属性时,如果该对象自身没有这个属性,就会去查找它的原型对象,以此类推,直到找到属性或者到达原型链的...

Global site tag (gtag.js) - Google Analytics