javascript中的Function对象是函数,函数的用途分为3类:
-
作为普通逻辑代码容器;
-
作为对象方法;
-
作为构造函数。
1.作为普通逻辑代码容器
function multiply(x, y){
return x*y;
}
函数multiply封装了两位数的乘法运算公式:
var product = multiply(128,128); // product = 16384
创建函数实例的方式有3种。第一种是声明式,即像声明变量一样,将通过function(){}标识符创建的匿名函数直接赋值给变量,以该变量作为调用时的函数名称:
var multiply = function(x, y){
return x*y;
}
第二种是定义式,即以function关键字后跟函数名称及(){}来直接定义命名函数,前面第一个multiply函数就是通过定义式创建的。
第三种是构造函数式,即通过new运算符调用构造函数Function来创建函数。这种方式极不常用,因此就不作介绍了。
在创建函数的3种方式中,声明式和定义式还存在细微的差别。比如下列代码中的函数采用声明式:
var example = function(){
return 1;
}
example();
var example = function(){
return 2;
}
example();
执行结果如下:
1
2
而如果采用定义式,即:
function example(){
return 1;
}
example();
function example(){
return 2;
}
example();
那么会得到另一种结果:
2
2
即,在采用定义式创建同名函数时,后创建的函数会覆盖先创建的函数。这种差别是由于javascript解释引擎的工作机制所导致的。
javascript解释引擎在执行任何函数调用之前,首先会在全局作用域中注册以定义式创建的函数,然后再依次执行函数调用。由于注册函数时,后定义的
函数重写了先定义的函数,因此无论调用语句位于何处,执行的都是后定义的函数。相反,对于声明式创建的函数,javascript解释引擎会像对待任何声
明的变量一样,等到执行调用该变量的代码时才会对变量求值。由于javascript代码是从上到下顺序执行的,因此当执行第一个example()调用
时,example函数的代码就是首先定义代码;而当执行第二个example()调用时,example函数的代码又变成了后来定义的代码。
2.作为对象方法
javascript在解析代码时,会为声明或定义的函数指定调用对象。所谓调用对象,就是函数的执行环境。如果函数体内有以关键字this声明的变量,则this引用的就是调用对象。
事实上,在普通的函数中,也存在调用对象,只不过这个调用对象是默认的全局window对象而已。例如:
var product = window.multiply(128,128); // product = 16384
这说明,默认情况下,在全局作用域中定义或声明的函数的调用对象就是window。
在面向对象编程中,通常将作为对象成员的函数称为方法。例如:
var dog = {};
dog.name = “heibao”;
dog.age = “3 months”;
dog.shout = function(){
return “Hello, My name is “+ this.name + ” and I am ” + this.age + ” old!”;
}
dog.shout(); // “Hello, My name is heibao and I am 3 months old!”
有意思的是,对象也可以借用其他对象的方法:
var cat = {};
cat.name = “xiaohua”;
cat.age = “2 years”;
cat.greet = dog.shout;
cat.greet(); // “Hello, My name is xiaohua and I am 2 years old!”
另外,使用函数对象的call和apply方法,还可以动态指定函数或方法的调用对象:
dog.shout.call(cat); // “Hello, My name is xiaohua and I am 2 years old!”
或者
dog.shout.apply(cat); // “Hello, My name is xiaohua and I am 2 years old!”
3.作为构造函数
javascript是通过构造函数来模拟面向对象语言中的类的。例如:
function Animal(sort, character){
this.sort = sort;
this.character = character;
}
以Animal作为构造函数,就可以像下面这样创建一个新对象:
var dog = new Animal(”mammal”,”four legs”);
创建dog的对象的过程如下:首先,new运算符创建一个空对象({}),然后以这个空对象为调用对象调用函数Animal,为这个空对象添加两个
属性sort和character,接着,再将这个空对象的默认constructor属性修改为构造函数的名称(即Animal;空对象创建时默认的
constructor属性值是Object),并且将空对象的__proto__属性设置为指向Animal.prototype——这就是所谓的对象
初始化。最后,返回初始化完毕的对象。这里将返回的新对象赋值给了变量dog。
dog.sort; // mammal
dog.character; // four legs
dog.constructor; // Animal
聪明的读者结合前面介绍的内容,可能会认为使用new运算符调用构造函数创建对象的过程也可以像下面这样来实现:
var dog = {};
Animal.call(dog, “mammal”,”four legs”);
表面上看,这两行代码与var dog = new Animal(”mammal”,”four legs”);是等价的,其实却不是。虽然通过指定函数的执行环境能够部分达到初始化对象的目的,例如空对象dog确实获得了sort和character这两个属性:
dog.sort; // mammal
dog.character; // four legs
dog.constructor; // Object —— 注意,没有修改dog对象默认的constructor属性
但是,最关键的是新创建的dog对象失去了通过Animal.prototype属性继承其他对象的能力。只要与前面采用new运算符调用构造函数
创建对象的过程对比一下,就会发现,new运算符在初始化新对象期间,除了为新对象添加显式声明的属性外,还会对新对象进行了一番“暗箱操作”——即将新
对象的constructor属性重写为Animal,将新对象的__proto__属性设置为指向Animal.prototype。虽然手工“初始化
对象”也可以将dog.constructor重写为Animal,但根据ECMA262规范,对象的__proto__属性对开发人员是只读的,对它的
设置只能在通过new运算符创建对象时由javascript解释引擎替我们完成。
javascript是基于原型继承的,如果不能正确设置对象的__proto__属性,那么就意味着默认的继承机制会失效:
Animal.prototype.greet = “Hi, good lucky!”;
dog.greet; // undefined
事实上,在Firefox中,__proto__属性也是可写的:
Animal.prototype.greet = “Hi, good lucky!”;
dog.__proto__ = Animal.prototype;
dog.greet; // Hi, good lucky!
但这样做只能在Firefox中行得通。考虑到在兼容多浏览器,必须依赖于new运算符,才能实现基于原型的继承。
转自:http://www.ok22.org/art_detail.aspx?id=52
分享到:
相关推荐
在面向对象的JavaScript中,类的成员可以根据它们与类和对象的关系分为“类成员”和“实例成员”。 ##### 8.2.1 实例属性和实例方法 **定义:** 实例成员包括实例属性和实例方法。每个对象实例都有自己的实例属性...
本PPT主要介绍了JavaScript中的OOP概念,包括Function对象的apply方法、自定义对象、封装、继承以及多态。 **apply()方法**是JavaScript中Function对象的一个内置方法,它的作用是改变函数调用时的上下文(即`this`...
这篇博客文章可能详细讨论了如何在JavaScript中实现面向对象编程。 在JavaScript中,面向对象主要通过以下三种方式实现: 1. **构造函数(Constructor)**:构造函数是一种特殊的函数,用于创建和初始化对象。我们...
`apply`是JavaScript中Function对象的一个内置方法,允许我们改变函数调用时的上下文(即`this`指向)以及传入参数。`apply`接受两个参数,第一个是`this`值,第二个是参数数组。它常用于模拟多态,使函数能适应...
JavaScript 中的 function 使用方法 JavaScript 中的 function 使用方法可以分为两种:...这将在 Animal 对象中添加一个 eat 方法。 JavaScript 中的 function 使用方法非常灵活,可以用来实现各种逻辑代码和对象。
面向对象编程(OOP)作为一种重要的编程范式,在JavaScript中也有独特的实现方式。 #### 二、JavaScript的特性概述 JavaScript是一种基于原型的语言,这意味着它不像传统的面向对象语言(如Java或C++)那样拥有类的...
本文将详细介绍JavaScript中的面向对象编程概念和技术,包括类定义、对象创建、继承、封装等内容。 #### 二、类定义和对象创建 ##### 2.1 类定义 在JavaScript中,“类”这一概念并不像在Java或C#这样的强类型...
JavaScript中的对象是编程的核心概念,它是语言特性和数据结构的基础。在JavaScript中,对象是一种复杂的数据结构,可以存储键值对,并且具有方法和属性。本文将深入探讨JavaScript对象的各个方面,包括创建、属性...
在JavaScript中,函数同样是一种对象,具有特殊的内部属性`[[Class]]`,其值为`"Function"`,表明它是函数类型。函数可以作为普通的对象使用,也可以作为构造函数来创建新的对象实例。在实现上,函数拥有特定的内部...
所有的对象都将继承Object的原型,包括Function对象。 例如,下面的代码: ``` function Foo() {}; var foo = new Foo(); alert(foo instanceof Foo); // true alert(foo instanceof Function); // false alert(foo...
在JavaScript中,创建对象是编程的基本操作之一,它支持多种方式来实现这一目的。这篇博客“javascript创建对象的方式(二)”可能详细介绍了在JavaScript中除了最基础的字面量语法之外的其他创建对象的方法。这里...
当尝试访问对象的一个属性时,JavaScript会首先在当前对象中查找,如果找不到,就会沿着原型链向上查找,直到找到为止。 4. **继承**:JavaScript支持多种继承方式,如原型链继承、构造函数继承、组合继承、原型式...
9. ES6新特性:随着ECMAScript 6(ES6)的发布,JavaScript引入了许多新特性,如类(class)、模块(module)、箭头函数(arrow function)等,这些都丰富了面向对象编程的能力。 通过以上内容,我们可以了解到...
面向对象编程是一种编程范式或概念,其中我们将数据和功能包装到对象中。在JavaScript中,数据可以是数字、布尔值、字符串、对象、数组、函数等对象内部的函数称为方法。实际上,术语“方法”只是一种了解我们正在...
2. 原型链:JavaScript中的每个对象都有一个内部属性`__proto__`,指向创建该对象的构造函数的原型。原型对象也是一个对象,可以包含共享的方法和属性。我们可以使用`prototype`属性来修改构造函数的原型: ```...
原型(prototype)是JavaScript中实现继承的关键,每个函数都有一个prototype属性,这个属性指向一个对象,该对象的属性和方法会被实例继承。当你创建一个新对象时,如果没有指定构造函数,那么这个新对象就会从...
在 JavaScript 中,函数对象对应的类型是 `Function`,正如数组对象对应的类型是 `Array`,日期对象对应的类型是 `Date` 一样。可以通过 `new Function()` 来创建一个函数对象,也可以通过 `function` 关键字来创建...
然而,ECMAScript中并没有引入类的概念,这就使得JavaScript中的对象与传统面向对象语言中的对象存在差异。 接下来,我们将详细探讨在进行面向对象与原型的学习时所需的条件。首先,基础是必不可少的。JavaScript的...
在JavaScript中,面向对象编程(OOP)是其核心概念之一,允许开发者通过类和对象来组织和管理代码,提高代码的可重用性和可维护性。 8.1 面向对象术语 面向对象编程的基础包括类、对象、继承和多态等概念。类是对象...