摘要:什么是函数引用的原话函数是一组可以随时随地运行的语句。函数是由这样的方式进行声明的关键字函数名一组参数,以及置于括号中的待执行代码。
什么是函数?
引用 W3School 的原话: 函数是一组可以随时随地运行的语句。 函数是 ECMAScript 的核心。 函数是由这样的方式进行声明的:关键字 function、函数名、一组参数,以及置于括号中的待执行代码。 函数的基本语法是这样的: function functionName(arg0, arg1, ... argN) { statements }
声明函数的几种方式
调用函数的几种方式
重载函数的实现
函数的独立性
声明函数
//声明函数的4种方法 //方法一 直接声明 function speak(word){ console.log(word) } //方法二 指定一个匿名函数 将其赋给一个变量,后面可以直接通过该变量调用该函数 var speak2 = function (word) { console.log(word); };//定义匿名函数需要注意最后需要加分号 //方法三 使用 Function对象 生成一个函数实例 var speak3 = new Function("word","console.log(word);"); //方法四 使用 Function函数 返回函数实例 var speak4 = Function("word","console.log(word);");
调用函数基本方法
speak("hello world for global !"); this.speak("hello world for this !"); window.speak("hello world for window !");
调用函数的高级方法
speak.call(null,"hello world with call !");//null 代表是用全局对象 window 调用 speak.apply(null,["hello world with apply !"]);
输出结果:
这里方法一大家不言而喻,简单明了,直接就是声明了一个函数,需要指出的是,默认写的函数在不依附其他对象的情况下均为全局函数,即成为 window 对象的成员,可以直接使用 window(Window 对象的实例,Window 对象实现了核心 JavaScript 所定义的所有全局属性和方法)调用,或者通过 this 调用,在这里JS 顶层代码中 this 指向的就是 window
每当我们使用方法一声明了一个函数的时候,实际是生成了一个 Function 对象的实例.即每个函数其实质都是一个 Function 对象实例.
注意:
JS 解析器每解析到一个函数的时候,都会在堆内存内划分出一块空间来存储创建该 Function 实例
方法二:
首先 JS 解析器解析到一个函数的时候,在堆内存内划分出一块空间来存储创建该 Function 实例,接着在当前栈内存
创建一个叫 speak2 的变量,这个变量有个值,这个值是一个地址,指向的是堆内存中的那个 Function 实例.实际上这就是大名鼎鼎的引用.
方法三:
与方法一和方法二不同的是,前两个方法都是声明好让解析器去解析,让解析器生成 Function 实例(就是上面声明的函数,解析器调用 Function 构造器来生成实例,这些步骤是我们看不到的),方法三是我们手动调用 Function 构造器生成 Function 实例(步骤掌握在自己的手里)
方法四:
与方法三不同的地方就是没有 new,在这里 new 与没 new 的区别就是当有 new 的时候 Function 函数充当一个构造器,new 后返回的就是实例化后得到的对象(此时Function 内部的 this指向的就是当前生成的对象),不使用 new 的话就是把 Function 函数看做一个普通函数直接调用,直接调用 Function 函数让其在内部(我们看不到)new 一个实例返回,本质是一样的.
call方法与 apply 方法
查看EcmaScript.js
可以看到 call 方法与 apply 方法的区别:
他们的第一个参数指的是调用该方法对象
call 方法的第二个参数是可变数组参数,即可以传入多个参数,非传入一个数组.传入的多个参数对应的是被调用方法的各参数.
apply 方法的第二个参数是一个数组对象,即可以直接传入一个数组对象,数组对象的每项对应的是被调用的方法的各参数.
实现重载函数
在 JS 中,并不像其他强类型语言一样可以声明重载函数,若在原先声明的函数后再声明一个不同参数数量的函数(JS是弱语言, 声明的函数不需要指明参数类型),解析器会用后面声明的函数覆盖前面声明的函数.那我们该如何实现呢.
arguments 对象
在每个函数都有一个arguments 属性,同样查看 EcmaScript.js
当生成一个函数实例后,解析器会赋给arguments 属性一个Arguments对象实例,这个实例是什么,再看 EcmaScript.js
可以得知其为一个对象同时为数组对象的子类,故可以将其当初数组对象使用.
函数实例中的 arguments对象(可以算是一个数组)的数组项内容便是我们在调用函数时进行传递的参数.只要我们有传参,这个属性就有数组项,否则数组长度为0,故我们可以通过arguments.length 来查看其得到的形参的数量.
有了上面的基础便可实现重载函数
这里引用 W3School 的例子
function doAdd() { if(arguments.length == 1) { alert(arguments[0] + 5); } else if(arguments.length == 2) { alert(arguments[0] + arguments[1]); } } doAdd(10); //输出 "15" doAdd(40, 20); //输出 "60"
函数的独立性
我们都知道,每当我们声明了一个函数,其实际为一个 Function 实例,那它独立在哪呢,如何体现呢
看一下代码:
function Dog(name,age){ this.name = name; this.age = age; this.showName = function () { console.log(this.name); } } function Cat(name,age){ this.name = name; this.age = age; this.showName = function () { console.log(this.name); } } var dog = new Dog("wangwang",2); var cat = new Cat("miaomiao",3); dog.showName(); cat.showName(); dog.showName.call(cat);
输出结果为:
解释:
每当我们在函数内使用 this 的时候,无非这几种情况:
1.作为构造器生成的实例对象
2.作为调用当前方法的对象
3.在 JS 顶层代码可以使用 this 代表 window 调用全局函数等
故当我们使用 call 方法调用某个对象的方法时,虽然从代码语义上看,这个所属方法是属于该对象的(showName 属于 Dog 或 Cat),但是由于函数有用其特殊的独立性即有以上几个关于 this 的特点,导致最终的结果是不同的.
当我们直接调用 dog 的 showName 方法时,showName 方法内的 this 指向的是该dog 对象(Dog 实例).
我们知道调用 call 方法时需要传入的第一个参数即为调用当前函数亦或方法的对象,此时被调用的方法的 this 指向的实际为传入的第一个参数.即当我们通过 call 调通 dog 的 showName 方法时,传入的第一个参数是 cat 对象,代表 dog 的 showName 方法的 this 此时指向的不是 dog 是 cat.最后输出的当然是 cat 的内容
最后指出:在对函数进行传参时,若传的是 JS 的基本类型,则为值传递,否则为引用传递.
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/86053.html
摘要:每个构造函数都有一个属性,用于设置所有实例对象需要共享的属性和方法。凭直觉,函数重载可以通过或者实现,这就不去管它了。自从年双十一正式上线,累计处理了亿错误事件,得到了金山软件等众多知名用户的认可。 译者按:能够读懂这篇博客的JavaScript开发者,运气不会太差... 原文: 10 JavaScript concepts every Node.js programmer must ...
摘要:因为是一条数据记录,也就是说,相当于是一个数据集。通常我们需要重载函数,声明,以及通过或为视图指定根元素。通过绑定视图的函数到模型的事件模型数据会即时的显示在中。实例属性参数以及类属性参数会被直接注册到集合的构造函数。 对于初学backbone.js的同学可以先参考我这篇文章:Backbone.js学习笔记(一) Backbone源码结构 showImg(https://segme...
阅读 3295·2021-11-12 10:36
阅读 2444·2021-11-02 14:43
阅读 2126·2019-08-30 14:23
阅读 3444·2019-08-30 13:08
阅读 906·2019-08-28 18:09
阅读 3109·2019-08-26 12:22
阅读 3081·2019-08-23 18:24
阅读 1992·2019-08-23 18:17