`
robinqu
  • 浏览: 88671 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

JavaScript Prototype基础

阅读更多
The prototype Property
引用
prototype property that refers to a predefined prototype object


Prototype属性是指一个早已确定的原型对象

Classes, Constructors, and Prototypes
引用
JavaScript does not support true classes the way that languages like Java, C++, and C# do.


JavaScript不支持真正的类继承,事实上是它是一个基于原型继承的,这和传统语言很不一样。

在JavaScript the Good Parts一书中,Douglas Crockford这样描述:
引用
It is Lisp in C's Clothing


在JS中,新建一个对象可以用对象的直接量{},或者通过构造函数

var array = new Array(10);
var today = new Date( );


定义我们自己的对象
// Define the constructor.
// Note how it initializes the object referred to by "this".
function Rectangle(w, h) {
    this.width = w;
    this.height = h;
    // Note: no return statement here
}

// Invoke the constructor to create two Rectangle objects.
// We pass the width and height to the constructor
// so that it can initialize each new object appropriately.
var rect1 = new Rectangle(2, 4);    // rect1 = { width:2, height:4 };
var rect2 = new Rectangle(8.5, 11); // rect2 = { width:8.5, height:11 };


在构造函数中始终要用this来引用当前对象,以来添加对象的属性

如果要添加方法:
// Create a Rectangle object
var r = new Rectangle(8.5, 11);
// Add a method to it
r.area = function( ) { return this.width * this.height; }
// Now invoke the method to compute the area
var a = r.area( );


当创建了对象之后再添加方法显得有些麻烦,我们可以这样:
function Rectangle(w, h) {
    this.width = w;
    this.height = h;
    this.area = function( ) { return this.width * this.height; }
}


引用
It is inefficient to use regular properties for methods that are intended to be shared by all objects of the same class (that is, all objects created with the same constructor).

这样问题就来了。以这种常规属性来存储对象方法是很没有效率的,这种方法本该是没个这样的对象实例所“共享”的,而不要每次新建一个对象都要新建一个这个方法的拷贝。

这时我们的原型对象就上场了

引用
a JavaScript object inherits properties from its prototype.

After creating the empty object, new sets the prototype of that object.
The prototype of an object is the value of the prototype property of its constructor function.

All functions have a prototype property that is automatically created and initialized when the function is defined.
The initial value of the prototype property is an object with a single property. This property is named constructor and refers back to the constructor function with which the prototype is associated.

JS的对象都会从它的原型那里继承属性。
我们在new一个对象的时候,new关键字就会设定对象的prototype属性,其值就是该对象的prototype对象的引用

函数也是对象,所以它也不例外有一个在定义时就有的prototype属性

Prototype属性初始时所指向的Prototype对象只有一个constructor属性,这个属性又指向了与这个prototype对象相关的构造函数

// The constructor function initializes those properties that
// will be different for each instance.
function Rectangle(w, h) {
    this.width = w;
    this.height = h;
}

// The prototype object holds methods and other properties that
// should be shared by each instance.
Rectangle.prototype.area = function( ) { return this.width * this.height; }


上面这个例子中,在构造函数里定义了每个实例都会有不同值的属性,而在其Prototype中定义共享的属性,这里是一个方法。

引用
The prototype object is associated with the constructor, and each object initialized by the constructor inherits exactly the same set of properties from the prototype. This means that the prototype object is an ideal place for methods and other constant properties.


在新建一个对象时,构造函数和Prototype对象共同作用。每个对象都会从Prototype中继承属性。我们可以将对象的常量和方法放在对象的Prototype里面。

引用

Inherited properties behave just like regular properties of an object. They are enumerated by the for/in loop and can be tested with the in operator.


继承过来的属性和普通属性一样,同样可以被for/in的循环中枚举出来。你只能通过对象的hasOwnProperty()方法来辨别:

var r = new Rectangle(2, 3);
r.hasOwnProperty("width");   // true: width is a direct property of r
r.hasOwnProperty("area");    // false: area is an inherited property of r
"area" in r;                 // true: "area" is a property of r


Therefore, property inheritance occurs only when you read property values, not when you write them. If you set the property p in an object o that inherits that property from its prototype, what happens is that you create a new property p directly in o. Now that o has its own property named p, it no longer inherits the value of p from its prototype. 


这种继承是可读的,但不可写。如果你试图修改对象中某个通过Prototype继承过来的属性,操作是可以完成的,结果是这个对象自己拥有了一个赋有新值的属性,它再也不继承自Prototype。

Extending Built-in Types
扩展内置的数据类型

// Returns true if the last character is c
String.prototype.endsWith = function(c) {
    return (c == this.charAt(this.length-1))
}

var message = "hello world";
message.endsWith('h')  // Returns false
message.endsWith('d')  // Returns true

引用

There is a strong argument against extending built-in types with your own methods; if you do so, you are essentially creating your own custom version of the core JavaScript API. Any other programmers who have to read or maintain your code will likely find it confusing if your code includes methods they have never heard of.

Note that you must never add properties to Object.prototype.

The technique shown here for extending built-in object types is guaranteed to work only for core JavaScript "native objects
."

There is one case in which it is safe and useful to extend the prototype of a built-in native class: to add standard methods to a prototype when an old or incompatible JavaScript implementation lacks them.


扩展JS内核的数据类型是十分具有争议的行为。例如上例中,我们扩展类String的内置方法,可是这样就相当于自定了JS的API,其他程序员不可能知道你的制定的这些特性。除非你想开发JS的大型框架。

另外,不要试图去扩展Object,这太危险了。JS的每个对象都从Object继承。如果你真的修改了Object的Prototype,那么用{}字面量新建的对象也是默认包含那些属性的,而不是我们预期中的“空”。

扩展核心API当然也可以来弥补兼容性的不足。
例如,IE4&5都不支持Function.apply()方法,那么我们可以定义它:
// IE 4 & 5 don't implement Function.apply( ).
// This workaround is based on code by Aaron Boodman.
if (!Function.prototype.apply) {
    // Invoke this function as a method of the specified object,
    // passing the specified parameters.  We have to use eval( ) to do this
    Function.prototype.apply = function(object, parameters) {
        var f = this;                // The function to invoke
        var o = object || window;    // The object to invoke it on
        var args = parameters || []; // The arguments to pass

        // Temporarily make the function into a method of o
        // To do this we use a property name that is unlikely to exist
        o._$_apply_$_ = f;

        // We will use eval( ) to invoke the method. To do this we've got
        // to write the invocation as a string. First build the argument list.
        var stringArgs = [];
        for(var i = 0; i < args.length; i++)
            stringArgs[i] = "args[" + i + "]";

        // Concatenate the argument strings into a comma-separated list.
        var arglist = stringArgs.join(",");

        // Now build the entire method call string
        var methodcall = "o._$_apply_$_(" + arglist + ");";

        // Use the eval( ) function to make the methodcall
        var result = eval(methodcall);

        // Unbind the function from the object
        delete o._$_apply_$_;

        // And return the result
        return result;
    };
}

分享到:
评论
4 楼 robinqu 2010-08-26  
truth315 写道
不好意思了,compu指的是getArea,粘贴过来时忘记改了.
不过在IE8,Firefox3.6,chrome都是可以运行的哦


那我搞错了~这里会作为对象的方法的运行,所以this还是指向该对象吧?
我没有去些demo~

可以考虑把这些方法写在一个对象下面,然后直接将该对象合并到需要这些方法的“类“的prototype里面。
3 楼 truth315 2010-08-25  
不好意思了,compu指的是getArea,粘贴过来时忘记改了.
不过在IE8,Firefox3.6,chrome都是可以运行的哦
2 楼 robinqu 2010-08-22  
truth315 写道
function Rectangle(w, h) {
    this.width = w;
    this.height = h;
    this.area = function( ) { return this.width * this.height; }
}

"以这种常规属性来存储对象方法是很没有效率的,这种方法本该是没个这样的对象实例所“共享”的,而不要每次新建一个对象都要新建一个这个方法的拷贝。"

如果代码是如下的样子:
function getArea(){
	return this.width * this.height;
}

function Rectangle(w, h) {
    this.width = w;
    this.height = h;
    this.area = compu;
}

会不会也导致“存储对象方法是很没有效率”?求答复



不明白第二段代码的第8行,compu是啥?如果你指的是
this.area = getArea;
你会悲剧的发现这个代码会报错的。
全局函数的this指向的是window对象⋯⋯

如果你的思想是把所有方法做成公共的全局函数,也是不错的,就是你在对象构造的时候比较麻烦,必须每个每个添加那些方法⋯⋯
1 楼 truth315 2010-08-21  
function Rectangle(w, h) {
    this.width = w;
    this.height = h;
    this.area = function( ) { return this.width * this.height; }
}

"以这种常规属性来存储对象方法是很没有效率的,这种方法本该是没个这样的对象实例所“共享”的,而不要每次新建一个对象都要新建一个这个方法的拷贝。"

如果代码是如下的样子:
function getArea(){
	return this.width * this.height;
}

function Rectangle(w, h) {
    this.width = w;
    this.height = h;
    this.area = compu;
}

会不会也导致“存储对象方法是很没有效率”?求答复

相关推荐

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

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

    Javascript-prototype.js 1.4版开发者手册

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

    JavaScript使用prototype定义对象类型

    From: JavaEye.com prototype提供了一套JavaScript面向对象基础设施,我们可以使用它来进行面向对象编程,定义对象类型方式如下: var Person = Class.create(); Person.prototype = { initialize : ...

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

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

    prototype.js_v1.6_含中英文手册

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

    Prototype入门

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

    prototype1.4旧中文版

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

    JavaScript入门经典(第4版 英文版+第3版中文版 附JavaScript参考手册)

    ****JavaScript入门经典(第4版 英文版+第3版中文版 附JavaScript参考手册)****《JavaScript入门经典(第4版)》主要内容:·循序渐进介绍JavaScript基础知识,包括JavaScript的含义、原理和功能·介绍用于创建...

    Prototype.js学习从简单开始

    基础性的介绍和应用实例讲解

    Prototype 1.5 中文文档 chm

    Prototype 最新的1.5 版中文文档,chm格式,很多人都在找。Prototype 是一个非常优秀的javascript基础类库,可以很好的支持Ajax,国外有多个基于此类库的扩展,这是最新的1.5中文文档,AJAX编程必备手册。

    prototype中文帮助文档

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

    jQuery(JavaScript框架)基础讲解

    jQuery是一个快速、简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(框架)于2006年1月由John Resig发布。jQuery设计的宗旨是“write Less,Do More”,即倡导写更少的代码,做更多的事情。...

    prototype and script.aculo.us框架

    ajax的两个框架,prototype是一个非常基础的框架,它对JavaScript固有的对象进行了扩展,还提供了若干自定义的类和对象,帮助简化JavaScript的开发。script.aculo.us框架是构建在prototype之上的JavaScript脚本库,...

    javascript学习笔记.docx

    1 JavaScript基本语法 1) 读未声明的变量会产生错误。写未声明的变量会是JavaScript环境自动产生一个全局变量。 2) 对于完全等同“===”,两个null或者两个undefined是等同的;但null与undefined是不等同的。 3) ...

    Prototype_api_cn

    中文Prototype Api 文档片段: 看到一个很好的东西在国内没有...prototype.js是一个非常优雅的javascript基础类库,对javascript做了大量的扩展,而且很好的支持Ajax,国外有多个基于此类库实现的效果库,也做得很棒。

    前端Javascript相关面试基础问答整理md

    从“原始值和引用值类型及区别”到“EventLoop事件循环&宏任务和微任务 ”,整理了Javascript学习和面试中遇到的一些基础和常见的问题。 总共包含33个问答,部分问题带有代码解答。 1. 原始值和引用值类型及区别 2. ...

    疯狂Ajax讲义:Prototype/jQuery+DWR+Spring+Hibernate整合开发(part01)

    《疯狂Ajax讲义:Prototype/jQuery+DWR+Spring+Hibernate整合开发》是疯狂Java体系丛书之一,前8章基本以XHTML、JavaScript和DOM编程为主,无须任何基础即可阅读;第9章以后的内容则需要掌握Spring、Hibernate等Java ...

    RICO 1.1 附 prototype 1.4

    做Ajax的朋友恐怕都听说过rico,这个是新出的 rico 1.1.0稳定版本,rico用到了prototype库,因此压缩包内还附带了prototype 1.4,另外还有RicoAjaxEngine.pdf ,可惜是英文的。 网址是:...

    prototype1.4版开发者手册

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

Global site tag (gtag.js) - Google Analytics