在 JavaScript 中,注意不要将 Array、Object 等类型指定给 prototype,除非您的应用需要那么做。先观察如下代码:

function Foo()
{
}
Foo.prototype.n = 123;
Foo.prototype.date = { year:2009, month:6, day:25 };

var f1 = new Foo();
var f2 = new Foo();
f1.n = 456;
f1.date.day = 24;
alert(f2.n); // 结果为 123
alert(f2.date.day);

f2.date.day 结果是多少?25?错,应该是 24。

这是由于 Array、Object 等与数字、字符串等基本的类型在内存中存储方式不同:

var items = new Array();

items 存储的并不是数组的内容,数组的内容存的另一个地方,而 items 变量只是存储这个数组的内存地址。

所以 Foo.prototype.date = { year:2009, month:6, day:25 }; 这句实际上已经指定了该 Object 的内存,证据

f1、f2 的 date 的内存位置不同,但其内存中指向的都是同一个 Object(date) 的内存,所以造成了上述的答案。

要让每个实例的 date 不同,可以这么解决:

function Foo()
{
}
Foo.prototype.date = null;
Foo.prototype.ini = function ()
{
    this.date = { year:2009, month:6, day:25 };
}

var f1 = new Foo();
f1.ini();
var f2 = new Foo();
f2.ini();
f1.date.day = 24;
alert(f2.date.day); // 结果为 25

或者直接放在“构造函数”中:

function Foo()
{
    this.date = { year:2009, month:6, day:25 };
}
Foo.prototype.date = null;

var f1 = new Foo();
var f2 = new Foo();
f1.date.day = 24;
alert(f2.date.day); // 结果为 25

当然,这两种解决办法中,实际上都可以将 Foo.prototype.date = null; 去掉,因为在为 this.date 赋值时,如果 this.date 不存在,会创建,相当于只要第一次使用 this.date 就创建了这个属性。

只不过加上 Foo.prototype.date = null; 可以在一些编辑器中自动感知 Foo 的属性,方便编程罢了。(更新:Visual Web Developer 2008 SP1 已经能够感知 this. 的东西,所以也可以去掉 Foo.prototype.date = null)

转自:http://www.cftea.com/c/2009/06/M4NFQTP1UY7A3FCE.asp

不要将 Array、Object 等类型指定给 prototype的更多相关文章

  1. java Object转换成指定的类型

    java Object转换成指定的类型 /** * Object转成指定的类型 * @param obj * @param type * @param <T> * @return */ p ...

  2. python 全栈开发,Day124(MongoDB初识,增删改查操作,数据类型,$关键字以及$修改器,"$"的奇妙用法,Array Object 的特殊操作,选取跳过排序,客户端操作)

    一.MongoDB初识 什么是MongoDB MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介 ...

  3. OpenGL.Vertex Array Object (VAO).

    OpenGL抛弃glEnable(),glColor(),glVertex(),glEnable()这一套流程的函数和管线以后,就需要一种新的方法来传递数据到Graphics Card来渲染几何体,我 ...

  4. c# 将object尝试转为指定对象

    主方法: /// <summary> /// 将object尝试转为指定对象 /// </summary> /// <param name="data" ...

  5. MongoDB之Array Object的特殊操作

    相比关系型数据库,Array[1,2,3,4,5]和Object{'name':'Wjs'}是MongoDB比较特殊的类型 db.Wjs.insert({"name":" ...

  6. MongoDB 之 Array Object 的特殊操作 MongoDB - 6

    相比关系型数据库, Array [1,2,3,4,5] 和 Object { 'name':'DragonFire' } 是MongoDB 比较特殊的类型了 特殊在哪里呢?在他们的操作上又有什么需要注 ...

  7. OpenGL.Vertex Array Object (VAO) [转]

    http://www.cppblog.com/init/archive/2012/02/21/166098.html 一 OpenGL抛弃glEnable(),glColor(),glVertex() ...

  8. 6,MongoDB 之 Array Object 的特殊操作

    相比关系型数据库, Array [1,2,3,4,5] 和 Object { 'name':'DragonFire' } 是MongoDB 比较特殊的类型了 特殊在哪里呢?在他们的操作上又有什么需要注 ...

  9. OpenGL.Vertex Array Object (VAO) 【转】

    http://www.cppblog.com/init/archive/2012/02/21/166098.html 一 OpenGL抛弃glEnable(),glColor(),glVertex() ...

随机推荐

  1. golang Aes

    package models import ( "bytes" "crypto/aes" "crypto/cipher" "err ...

  2. .Net之垃圾回收算法

    垃圾回收器检测托管堆中是否有应用程序不在使用的任何对象,如果一次垃圾回收之后,堆栈没有可用的内存,new操作符将会抛出OutOfMemoryException(内存溢出). 每一个应用程序都包含一组根 ...

  3. sql中Statement与PreparedStatement的区别

    1.Statement用于执行静态sql语句,在执行时,必须指定一个事先准备好的sql语句,也就是说sql语句是静态的. 2.PrepareStatement是预编译的sql语句对象,sql语句被预编 ...

  4. jsoup_解析任意网站,做任意网站客户端

    jsoup是一个解析网页源码的开源库,他能按照给定的规则提取出一个网页中的任意元素,和其他网页解析库不同的是,他提取网页内容的方式和css.jquery的选择器非常相似.因此如果你懂得前端的知识,只需 ...

  5. leetcode算法刷题(五)——动态规划(三)

    今天的题目不是leetcode上面的.只是觉得动态规划还是不算很熟练,就接着找了点DP的题练练 最长递增子序列的长度 题目的意思:传入一个数组,要求出它的最长递增子序列的长度.例如:如在序列1,-1, ...

  6. linux---finger命令

    问题:CentOS7默认是没有安装finger这个程序的,所以finger命令执行不了. 解决方案: 1.安装finger yum -y install finger

  7. css案例学习之div与span的区别

    代码: <html> <head> <title>div 标记范例</title> <style type="text/css" ...

  8. KVC在定义Model类中的妙用

    @我们应用程序使用MVC架构的话,对于处理数据类,我们会单独的定义Model类,在里面为要展示的属性进行初始化赋值,一般採用的方法是通过定义相应的属性,挨个赋值.如今我要介绍的就是通过KVC,key- ...

  9. C++隐式转换

    #include <iostream> using namespace std; class A { int a; public: A(int n):a(n) { cout << ...

  10. Linux下patch打补丁命令

    此命令用于为特定软件包打补丁,他使用diff命令对源文件进行操作. 基本命令语法: patch [-R] {-p(n)} [--dry-run] < patch_file_name p:为pat ...