`
deng131
  • 浏览: 673835 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

new FunctionName()的内部机制

阅读更多
测试代码:

function Dog(name) {
    this.name = name;
    Dog.prototype = {
        shout: function() { alert("I am " + this.name); }
    };
}
var dog1 = new Dog("Dog 1");
dog1.shout();

上面的代码看起来很“优美”,可一运行,却报错:“Object doesn’t support this property or method”.

在 YUI 3 学习笔记:oop 中,曾提到过,对于代码:

Fn() {};
var fn = new Fn();

new Fn() 的实际构造过程可以等价为以下伪代码:

var o = {__proto__: Fn.prototype};
Fn.apply(o);
return o;

理解了 new 的构造过程,我们可以分析上面的实例了。

首先,JS引擎在遇到函数声明 function Dog(…) 时,会给函数对象添加 prototype 属性,伪代码如下:

Dog.prototype = {constructor: Dog};

当运行到 var dog1 = new Dog(“Dog 1″) 时,内部操作:

var o = {__proto__: Dog.prototype};
Dog.apply(o);
return o;

也许你已经知道问题所在了。为了更清楚,添加点注释:

// Dog.prototype = {constructor: Dog};
var o = {__proto__: Dog.prototype};
// 此时,o = {__proto__: {constructor: Dog}}
Dog.apply(o);
// 此时,Dog.prototype = {shout: function(){...}}
return o;

显然,运行 dog1.shout() 时,dog1 的确没有 shout 方法。

考考大家:

function Dog(name) {
    this.name = name;
    Dog.prototype = {
        shout: function() { alert("I am " + this.name); }
    };
}
var dog1 = new Dog("Dog 1");
var dog2 = new Dog("Dog 2");
dog2.shout();
dog1.shout();

请问运行结果是什么?

最后,想大声疾呼:作为一门语言,JavaScript 有自己的脾性。用 Java 等代码方式去书写 JavaScript 代码,是不妥当的。在不使用框架的情况下,一次性添加多个方法时,推荐以下书写风格:

function Dog(name) {
    this.name = name;
}
Dog.prototype = {
        constructor: Dog,
        shout: function() { /* ... */ },
        run: function() { /* ... */ }
    };

分享到:
评论

相关推荐

    获得Windows XP 内部版本号,vc++ MFC程序

    紧随其后的是NT(New Technology)特定的头,这部分包含了Windows特有的信息,如PE标志、文件头大小、程序入口点地址等。 在NT头中,有一个名为`IMAGE_OPTIONAL_HEADER`的数据结构,它包含了Windows版本信息。其中...

    javascript教程

    在示例中,`addn`函数返回了一个内部函数`addn2`,这个内部函数保留了对`ibasenum`的引用,即使`addn`已经执行完毕。 #### 对象的应用 - **声明和实例化**:在JavaScript中,对象是通过关键字`new`后跟要实例化的...

    JS 构造函数

    构造函数并不像普通函数那样通过`functionName()`来调用,而是通过`new`关键字创建一个新对象,并将这个新对象作为上下文(`this`关键字指向新对象)。例如: ```javascript var obj = new ClassName(); ``` 3....

    关于js类的定义

    遇到的问题,首先是js对象的封装,js没有提供类的机制,唯一... } 不过这样有一个问题,每当我new一个新的myClass实例的时候,内部的function都会重新开辟空间,返回引用给functionName。但这个和我们设想的类不一致,

    用友NCC新增编辑公式

    在用友NCC(New Century Cloud,新一代企业级云服务)中,用户有时需要根据特定业务需求创建自定义公式。这通常涉及到对公式编辑器的深入理解和自定义函数的编写。以下是如何在用友NCC中新增自定义公式的详细步骤及...

    使用_Dojo_的_Ajax_应用开发进阶教程

    `arguments` 对象允许在函数内部访问传递给函数的所有参数,即使这些参数没有明确地定义为形式参数。 - **arguments**: 是一个类数组对象,可以使用索引或 `arguments.length` 来访问参数。 - **函数参数**: 即使...

    flex加载as2写的swf,内容是一个很雷的网页游戏AD

    当Flex(AS3)需要加载AS2的SWF时,它依赖于Flash Player的内部兼容性层。Flash Player可以同时执行AS2和AS3代码,因此在加载过程中不会出现兼容问题。然而,这意味着AS2 SWF的行为可能受到Flash Player版本的影响...

    delphi CALL原码

    - 手动分配的内存(如使用New或AllocMem)需要在使用后使用Free或FreeMem释放。 6. **返回地址和堆栈:** - 当调用函数或过程时,编译器会在堆栈中保存当前指令地址,这就是返回地址。 - 调用结束后,程序会从...

    jsp 课后习题 第2章

    Java的垃圾回收机制负责自动检测不再使用的对象并销毁它们,以回收内存资源。 5. 构造方法: 构造方法是与类同名的特殊方法,无返回值,用于初始化新创建的对象。在创建新对象时,构造方法会自动调用,用于设置...

    C++期末复习--2.练习题_填空.docx

    16. 函数形参的作用域是该函数的**局部作用域**,仅在函数内部有效。 17. 程序的编译是以**源文件**为单位进行的。 18. 执行`int *p = new int`操作得到的一个动态分配的整型对象,其值未初始化,不确定。 19. ...

    C++期末复习--2.练习题_填空汇总.pdf

    42. 类外定义成员函数时,应使用类名和双点号`::`分隔符,如`ClassName::FunctionName`。 43. 将类外定义的成员函数声明为内联,需在函数原型或函数定义前加上`inline`关键字。 44. 假定`AA`是一个类,成员函数...

    ASP.NET C#语法用法大全

    - 函数与方法:定义函数使用`void FunctionName(params)`。参数可以是值类型或引用类型,返回值可选。例如,一个简单的函数定义:`int Add(int a, int b) { return a + b; }` 2. **面向对象编程**: - 类与对象:...

    Swift - Swift Programming in easy steps

    在Swift中定义函数的基本格式如下:`func functionName(parameters) -> returnType { ... }`。例如,定义一个计算两数之和的函数:`func add(a: Int, b: Int) -> Int { return a + b }`。 #### User Interaction ...

    C++ 总结(总结+实例)

    - **堆区**:也称为动态分配区域,主要通过 `new` 和 `malloc` 等操作进行分配,用于存储动态创建的对象。 #### 三. 语句 C++ 中的语句是构建程序的基本单位,常见的语句包括赋值语句、控制语句(如 if、for、...

    求职c++后台工作的重点总结

    1. **方法**:可以通过在循环内部增加计数器,并记录日志的方式来监控循环次数是否异常增长,从而判断是否存在死循环。 2. **步骤**: - 在循环体内添加计数器,记录循环执行的次数。 - 设置阈值,如果循环次数...

    JavaScript 类的定义和引用 JavaScript高级培训 自定义对象

    类属性可以直接通过函数名来引用,语法格式通常类似于`functionName.propertyName`。 例如,对于一个自定义的类,我们可以这样定义类属性: ```javascript function MyClass() {} MyClass.classProperty = "Class ...

    微软070-480认证(HTML5 Javascript CSS3)

    - **定义与调用**:`function functionName() {}`。 - **作用域**:函数内部与外部的作用域差异。 **2.3 对象与原型** - **对象创建**:字面量 `{}` 或 `new Object()`。 - **原型链**:对象继承机制,实现方法...

    haXe2语言参考手册(英文)

    - 示例: `functionName(args...)`. - **创建新对象** (`New`): - 创建类的新实例。 - 示例: `new ClassName()`. - **数组** (`Arrays`): - 定义数组的基本语法。 - 示例: `[1, 2, 3]`. - **条件语句** (`If`): ...

Global site tag (gtag.js) - Google Analytics