测试代码:
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() { /* ... */ }
};
分享到:
相关推荐
紧随其后的是NT(New Technology)特定的头,这部分包含了Windows特有的信息,如PE标志、文件头大小、程序入口点地址等。 在NT头中,有一个名为`IMAGE_OPTIONAL_HEADER`的数据结构,它包含了Windows版本信息。其中...
在示例中,`addn`函数返回了一个内部函数`addn2`,这个内部函数保留了对`ibasenum`的引用,即使`addn`已经执行完毕。 #### 对象的应用 - **声明和实例化**:在JavaScript中,对象是通过关键字`new`后跟要实例化的...
构造函数并不像普通函数那样通过`functionName()`来调用,而是通过`new`关键字创建一个新对象,并将这个新对象作为上下文(`this`关键字指向新对象)。例如: ```javascript var obj = new ClassName(); ``` 3....
遇到的问题,首先是js对象的封装,js没有提供类的机制,唯一... } 不过这样有一个问题,每当我new一个新的myClass实例的时候,内部的function都会重新开辟空间,返回引用给functionName。但这个和我们设想的类不一致,
在用友NCC(New Century Cloud,新一代企业级云服务)中,用户有时需要根据特定业务需求创建自定义公式。这通常涉及到对公式编辑器的深入理解和自定义函数的编写。以下是如何在用友NCC中新增自定义公式的详细步骤及...
`arguments` 对象允许在函数内部访问传递给函数的所有参数,即使这些参数没有明确地定义为形式参数。 - **arguments**: 是一个类数组对象,可以使用索引或 `arguments.length` 来访问参数。 - **函数参数**: 即使...
当Flex(AS3)需要加载AS2的SWF时,它依赖于Flash Player的内部兼容性层。Flash Player可以同时执行AS2和AS3代码,因此在加载过程中不会出现兼容问题。然而,这意味着AS2 SWF的行为可能受到Flash Player版本的影响...
- 手动分配的内存(如使用New或AllocMem)需要在使用后使用Free或FreeMem释放。 6. **返回地址和堆栈:** - 当调用函数或过程时,编译器会在堆栈中保存当前指令地址,这就是返回地址。 - 调用结束后,程序会从...
Java的垃圾回收机制负责自动检测不再使用的对象并销毁它们,以回收内存资源。 5. 构造方法: 构造方法是与类同名的特殊方法,无返回值,用于初始化新创建的对象。在创建新对象时,构造方法会自动调用,用于设置...
16. 函数形参的作用域是该函数的**局部作用域**,仅在函数内部有效。 17. 程序的编译是以**源文件**为单位进行的。 18. 执行`int *p = new int`操作得到的一个动态分配的整型对象,其值未初始化,不确定。 19. ...
42. 类外定义成员函数时,应使用类名和双点号`::`分隔符,如`ClassName::FunctionName`。 43. 将类外定义的成员函数声明为内联,需在函数原型或函数定义前加上`inline`关键字。 44. 假定`AA`是一个类,成员函数...
- 函数与方法:定义函数使用`void FunctionName(params)`。参数可以是值类型或引用类型,返回值可选。例如,一个简单的函数定义:`int Add(int a, int b) { return a + b; }` 2. **面向对象编程**: - 类与对象:...
在Swift中定义函数的基本格式如下:`func functionName(parameters) -> returnType { ... }`。例如,定义一个计算两数之和的函数:`func add(a: Int, b: Int) -> Int { return a + b }`。 #### User Interaction ...
- **堆区**:也称为动态分配区域,主要通过 `new` 和 `malloc` 等操作进行分配,用于存储动态创建的对象。 #### 三. 语句 C++ 中的语句是构建程序的基本单位,常见的语句包括赋值语句、控制语句(如 if、for、...
1. **方法**:可以通过在循环内部增加计数器,并记录日志的方式来监控循环次数是否异常增长,从而判断是否存在死循环。 2. **步骤**: - 在循环体内添加计数器,记录循环执行的次数。 - 设置阈值,如果循环次数...
类属性可以直接通过函数名来引用,语法格式通常类似于`functionName.propertyName`。 例如,对于一个自定义的类,我们可以这样定义类属性: ```javascript function MyClass() {} MyClass.classProperty = "Class ...
- **定义与调用**:`function functionName() {}`。 - **作用域**:函数内部与外部的作用域差异。 **2.3 对象与原型** - **对象创建**:字面量 `{}` 或 `new Object()`。 - **原型链**:对象继承机制,实现方法...
- 示例: `functionName(args...)`. - **创建新对象** (`New`): - 创建类的新实例。 - 示例: `new ClassName()`. - **数组** (`Arrays`): - 定义数组的基本语法。 - 示例: `[1, 2, 3]`. - **条件语句** (`If`): ...