`
holdbelief
  • 浏览: 704992 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JavaScript 函数是最棒的

阅读更多

JavaScript 函数是最棒的

在很多编程语言中,函数和对象通常被视为两样不同的东西。在 JavaScript 中,其差别很模糊 — JavaScript 函数实际上是具有与它关联的可执行代码的对象。请如此看待普通函数:

 

function func(x) {
    alert(x);
}
func(“blah”);

 这就是通常在 JavaScript 中定义函数的方法。但是,还可以按以下方法定义该函数,您在此创建匿名函数对象,并将它赋给变量 func

var func = function(x) {
    alert(x);
};
func(“blah2”);

 甚至也可以象下面这样,使用Function构造函数:

var func = new Function(“x”, “alert(x);”);
func(“blah3”);

Function的第一个参数是函数的入参,第二个参数是函数的主体部分,如果有多个输入参数的写法如下:

//方法1
var obj = new Object();
obj.test = "obj的Test";

var func = new Function
(
     ["x","y","z"], 
     "alert(x);alert(y);alert(z.test);"
);

func("blah1","blah2",obj);

 

// 方法2
var obj = new Object();
obj.test = "obj的Test";

var func = new Function
(
     "x,y,z", 
     "alert(x);alert(y);alert(z.test);"
);

func("blah1","blah2",obj);

 

// 方法3
var obj = new Object();
obj.test = "obj的Test";

var func = new Function
(
     "x","y",z", 
     "alert(x);alert(y);alert(z.test);"
);

func("blah1","blah2",obj);

 

以上三种方法都可以实现定义多个入参的函数。并且演示了如何定义一个入参是对象的函数的定义。

关于Function的小结,如下面代码中的注释:

/*
 * Function可以有多个入口参数,最后一个参数最为方法体。
 */
var MyObject = new Function("msg","alert(msg);");

var o = new MyObject("Hello world!");

此示例表明函数实际上只是支持函数调用操作的对象。最后一个使用Function 构造函数来定义函数的方法并不常用,但它展示的可能性非常有趣,因为您可能注意到,该函数的主体正是Function构造函数的String参数。这意味着,您可以在运行时构造任意函数。

为了进一步演示函数是对象,您可以像对其他任何JavaScript对象一样,在函数中设置或添加属性:

function sayHi(x)
{
    alert(“Hi, “ + x + “!”);
}
sayHi.text = “Hello World!”;
sayHi[“text2”] = “Hello World... again.”;

alert(sayHi[“text”]); // displays “Hello World!”

 作为对象,函数还可以赋给变量、作为其它函数的值返回,并可以作为对象的属性或数组元素进行存储等等。图1提供了这样一个示例。

Figure 1 JavaScript中的函数是最棒的

// assign an anonymous function to a variable
var greet = function(x) {
    alert(“Hello, “ + x);
};
greet(“MSDN readers”);

// passing a function as an argument to another
function square(x) {
    return x * x;
}
function operateOn(num, func) {
    return func(num);
}
// displays 256
alert(operateOn(16, square));

// functions as return values
function makeIncrementer() {
    return function(x) { return x + 1; };
}
var inc = makeIncrementer();
// displays 8
alert(inc(7));

// functions stored as array elements
var arr = [];
arr[0] = function(x) { return x * x; };
arr[1] = arr[0](2);
arr[2] = arr[0](arr[1]);
arr[3] = arr[0](arr[2]);
// displays 256
alert(arr[3]);

// functions as object properties
var obj = { “toString” : function() { return “This is an object.”; } };
// calls obj.toString()
alert(obj);

 记住这一点后,向对象添加方法将是很容易的事情:只需要选择名称,然后将函数赋值给该名称。因此,我通过将匿名函数分别赋值给相应的方法名称,在对象中定义了三个方法:

var myDog = {
    “name” : “Spot”,
    “bark” : function() { alert(“Woof!”); },
    “displayFullName” : function() {
        alert(this.name + “ The Alpha Dog”);
    },
    “chaseMrPostman” : function() { 
        // implementation beyond the scope of this article 
    }    
};
myDog.displayFullName(); 
myDog.bark(); // Woof!

 注意myDog.displayFullName(); myDog.bark();调用方法时要加上括号,因为虽然是将方法赋给了对象的属性,但他们还是方法阿。

C++/C# 开发人员应当很熟悉displayFullName 函数中使用的“this”关键字 — 它引用一个对象,通过对象调用方法(使用Visual Basic的开发人员也应当很熟悉它, 它在Visual Basic中叫做“Me”)。因此在上面的示例中,displayFullName中的"this"的值是myDog对象。但是,"this" 的值不是静态的。通过不同对象调用 “this” 时, 它的值也会更改以便指向相应的对象,如图2所示:

 

Figure2 "this" 随对象更改而更改

function displayQuote() {
    // the value of “this” will change; depends on 
    // which object it is called through
    alert(this.memorableQuote);    
}

var williamShakespeare = {
    'memorableQuote': 'It is a wise father that knows his own child.', 
    'sayIt' : displayQuote
};

var markTwain = {
    'memorableQuote': 'Golf is a good walk spoiled.', 
    'sayIt' : displayQuote
};

var oscarWilde = {
    'memorableQuote': 'True friends stab you in the front.' 
    // we can call the function displayQuote
    // as a method of oscarWilde without assigning it 
    // as oscarWilde’s method. 
    //”sayIt” : displayQuote
};

williamShakespeare.sayIt(); // true, true
markTwain.sayIt(); // he didn’t know where to play golf

// watch this, each function has a method call()
// that allows the function to be called as a 
// method of the object passed to call() as an
// argument. 
// this line below is equivalent to assigning
// displayQuote to sayIt, and calling oscarWilde.sayIt().
displayQuote.call(oscarWilde); // ouch!
// oscarWilde.displayQuote(); 
// 这么写则会抛出异常(IE:对象不支持此属性或方法)
// 由此可以看到call函数的强大。

 

图2中的最后一行表示的是将函数作为对象的方法调用的另一种方式。 请记住,JavaScript中的函数是对象。每个函数对象都有一个名为call的方法,它将函数(displayQuote)作为第一个参数(oscarWilde)的方法进行调用。就是说,作为函数第一个参数传递给call的任何对象都将在函数调用中成为 "this" 的值。这一技术对于调用基类构造函数来说非常有用,稍后将对此进行介绍。

注意在williamShakespeare和markTwain对象中,将displayQuote()函数赋给了这两个对象,而并没有将它赋给oscarWilde对象,williamShakespeare和markTwain对象调用displayQuote()函数如果还比较好理解的话,那么oscarWilde对象调用displayQuote()函数就比较难于理解了。

call()方法只是让oscarWilde对象调用displayQuote()方法,并没有将displayQuote()作为一个属性赋给oscarWilde对象。这与
var markTwain =
{
    'memorableQuote': 'Golf is a good walk spoiled.',
    'sayIt' : displayQuote
};
有着明显的不同。后者是使displayQuote方法称为对象的成员之一,而call不是,它只是调用。我们看到
// oscarWilde.displayQuote();
displayQuote.call(oscarWilde); // ouch!
// oscarWilde.displayQuote();
// 这么写则会抛出异常(IE:对象不支持此属性或方法)
oscarWilde.displayQuote();这一句不论放在call方法前还是放在call方法后执行都会抛异常。
 

有一点需要记住,绝不要调用包含"this"(却没有所属对象)的函数。否则,将违反全局命名空间,因为在该调用中,"this" 将引用全局对象,而这必然会给您的应用程序带来灾难。例如,下面的脚本将更改JavaScript的全局函数 isNaN 的行为。一定不要这样做!

alert(“NaN is NaN: “ + isNaN(NaN));
function x() {
    this.isNaN = function() { 
        return “not anymore!”;
    };
}
// alert!!! trampling the Global object!!!
x();

alert(“NaN is NaN: “ + isNaN(NaN));




 注意:isNaN()是JavaScript的一个全局函数,运行上面的程序可以看到,两次执行isNaN(NaN)结果是不一样的,这是因为执行x()函数时,x()函数中的"this"并没有指向某一个对象,这是"this"指向全局函数,则x()将i全局函数sNaN()的实现修改了。

到这里,我们已经介绍了如何创建对象,包括它的属性和方法。但如果注意上面的所有代码段,您就会发现属性和方法是在对象定义本身中进行硬编码的。但如果需要更好地控制对象的创建,该怎么办呢?例如,您可能需要根据某些参数来计算对象的属性值。或者,可能需要将对象的属性初始化为仅在运行时才能获得的值。也可能需要创建对象的多个实例(此要求非常常见)。

 

在C#中,我们使用类来实例化对象实例。但是JavaScript与此不同,因为它没有类。您将在下一节中看到,您可以充分利用这一情况:函数在于"new"运算符一起使用时,函数将充当构造函数。

下一节 ——  “构造函数而不是类 ”                                                                                       返回首页: Top

 

分享到:
评论

相关推荐

    一个超棒可视化学习函数式编程的游戏

    标题中的“一个超棒可视化学习函数式编程的游戏”暗示了我们即将探讨的是一款结合了教育与娱乐元素的游戏,它的目标是帮助用户通过游戏化的方式学习函数式编程。这款游戏可能使用了直观的图形界面来呈现编程概念,...

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

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

    JavaScript_一个很棒的Udemy课程的入门包.zip

    "JavaScript_一个很棒的Udemy课程的入门包.zip"很可能包含了一个精心设计的课程结构,旨在引导初学者逐步熟悉JavaScript的基础概念和高级特性。 JavaScript的核心知识点包括: 1. **基础语法**:变量声明(var, ...

    一组特别棒的CSS+JavaScript文字动态效果源码

    开发者可以通过查看和学习这些源码,了解如何使用HTML5标签、CSS3选择器和JavaScript函数来创建动态文字。例如,一个简单的文字淡入淡出效果可能使用了CSS3的`opacity`属性和JavaScript的`setTimeout`函数,而复杂的...

    很棒的一套javascript教程

    JavaScript支持面向对象编程、命令式编程和函数式编程等风格,具备高度的灵活性和可扩展性。 ### 经典JavaScript知识点概述 #### 1. 基础语法 - **变量声明**:使用`var`、`let`和`const`关键字来声明变量。 - **...

    很棒的JavaScript日历和时间选择插件

    JavaScript日历和时间选择插件...以上就是关于“很棒的JavaScript日历和时间选择插件”的一些核心知识点。在实际开发中,还需要根据具体的需求和技术栈,结合现有的库和框架,如jQuery、React、Vue等,进行定制化实现。

    JavaScript_很棒的React Native组件新闻工具和学习材料.zip

    学习JavaScript和React Native,你需要理解JavaScript的基础语法,包括变量、函数、对象和数组。此外,掌握React的概念,如组件、props和state,以及生命周期方法,是至关重要的。React Native则在此基础上增加了对...

    Stickman Hangman Game in JavaScript with Source Code.zip

    JavaScript的`addEventListener`函数可以用于监听这些事件,并在事件触发时执行相应的处理函数。 2. **DOM操作**:JavaScript可以通过DOM(文档对象模型)接口与HTML元素进行交互,如创建、修改和删除元素。在本...

    Awesome-JavaScript-Projects:此存储库包含很棒的原始JavaScript项目

    很棒JavaScript项目 您是Web开发的新手,并且想深入研究Javascript吗? 您是否正在寻找一些很棒的Javascript项目,每个项目都将教给您一个重要的Javascript概念? 您是否想为一些Awesome Javascript项目做出贡献...

    ScriptDeck:ScriptDeck是一种在计算机上远程执行预配置的javascript函数的方法

    ScriptDeck ScriptDeck是一种在计算机上远程执行自己的javascript函数的方法。 ScriptDeck附带一个Web服务器和2个Websocket,这些Websocket承载一个配置网页,使您可以使用预先编写的或自己的功能轻松配置自己的按钮...

    table光棒效果 table光棒效果

    根据提供的文件信息,这里主要涉及的...通过以上分析可以看出,给定的“table光棒效果”主要涉及到了表格的基本使用以及通过 JavaScript 或 CSS 实现交互效果的方法。希望以上内容能够帮助您更好地理解和实现这一功能。

    html+css+javascript实现抖音最火的罗盘时钟源码,时钟数字罗盘

    - **事件监听**:为了使时钟实时更新,JavaScript需要监听时间的改变,这通常通过`setInterval`函数实现,每隔一定间隔(如1秒)执行一次更新时间的函数。 - **日期和时间处理**:JavaScript的`Date`对象可以帮助...

    2014 年最热门的21款JavaScript框架推荐

    下面,我们将会介绍 2014 年最火的 21 款JavaScript 框架,专为前端开发者准备的哦:)众所周知, JavaScript 框架是 JavaScript编程语言最棒的特性之一。  JavaScript 框架是预先编写好的 JavaScript 库,为基于 ...

    Funfun:用于 JavaScript 的函数式编程实用程序库

    我喜欢 Underscore 和 Lodash —— 在 JavaScript 中使用 Lisp 和 Haskell 等函数式语言中的许多我习惯的操作非常棒。 尽管如此,他们仍有很多不足之处。 “包装”对象很笨重,并且很难将非 Underscore 函数混合到...

    JavaScrip例子学习(里面有N多的例子供你参考,超棒的))

    此外,JavaScript还支持匿名函数和箭头函数,这些在编写回调函数和处理数组时非常常见。 接着,深入学习JavaScript的对象和原型链,这是JavaScript面向对象编程的基础。你需要理解对象属性的访问方式(dot notation...

    reducers-creator:Reducers Creator是一个很棒的小型javascript程序包,可让您轻松直观地创建reducer函数。 主要用于创建redux reducer

    减速机造物主如果要在redux项目中使用它,请查看以下软件包: 描述Reducers Creator是一个很棒的小型javascript程序包,可让您轻松直观地创建reducer函数。 主要用于创建redux减速器。 请参阅: 安装npm install ...

    很棒的用于信息提示的JS库

    标题中的“很棒的用于信息提示的JS库”指的是一个专门设计用于在网页中显示提示信息的JavaScript库。这种库通常提供了丰富的自定义选项,能够帮助开发者创建出吸引人的、交互式的提示效果,以提升用户体验。...

    相当棒的js日历

    在这个场景下,我们关注的是一个名为“相当棒的js日历”的项目,它提供了美观且可自定义样式的日历功能。这个日历应用的核心是通过JavaScript实现,同时也涉及到CSS来调整样式,使得日历看起来更加吸引人。 首先,`...

    9款很棒的网页绘制图表JavaScript框架脚本

    它支持多种图表类型,如线图、面积图、散点图、饼图和函数级数,且所有细节都可自定义。 8. **fgCharting** fgCharting是另一个基于jQuery的简单图表生成器,同样支持多种图表类型和自定义参数,使得创建图表变得...

    棒打疯猫HTML5游戏源码

    游戏循环(Game Loop)通常由JavaScript实现,这是一个不断执行的函数,用来更新游戏状态、处理用户输入和渲染画面。使用setTimeout()或requestAnimationFrame()来控制循环的执行频率,以确保游戏流畅运行。 此外,...

Global site tag (gtag.js) - Google Analytics