摘要:英文原文中本来是,而翻译成第一类公民其实就是一种比喻。所以,通过上述的结果,我们发现在中不管我们是用构造函数创建的对象还是用本身提供的数据类型创建的对象都源自于。使用可以解除函数体内代码和函数名的耦合状态。
作为一个Jser,不光要会用js,还要明白它的运行原理,不然就会一直停留在表面。
函数在JavaScript中被称作第一等公民,这个第一等公民是什么鬼?看看知乎上是怎么回答的。就像我的引路人刚开始跟我说的要想学好一门语言,就要先掌握好一门外语(英语)一样,因为这些计算机编程语言或解释器语言基本都是源于老外开发,所以要想学到原汁原味的东西,查看英文文档是必不可少的。
英文原文中本来是 first-class object ,而翻译成 第一类公民 其实就是一种比喻。从这里可以知道两点:
函数本质上也是对象,
可以用函数实现其它的任何对象
函数的用法可以动态的创建函数 (new Function())
这种方式不常用,也不推荐。具体原因是(来自于JavaScript高级程序设计):这种语法会导致解析两次代码,从而影响性能。
可以将函数赋值给变量(函数表达式)
可以将函数最为一个参数传递给另一个函数(回调函数)
函数可以包含自己的属性和方法(构造函数)
将一个函数作为另一个函数的返回值
对象数组的排序,代码如下:
function compare(prop) { return fucntion(obj1, obj2) { var v1 = obj1[prop], v2 = obj2[prop] return v1 > v2 ? 1 : v1 < v2 ? -1 : 0 } } var arr = [{ name: "li", age: 18 }, { name: "an", age: 19 }, { name: "tian", age: 18 }] arr.sort(compare("name"))函数与对象之间的关系
通过上面的描述,不管之前知道不知道,但是现在应该知道,我们可以通过函数来创建对象。
代码说明:
function Robot(name) { this.name = name } var robert = new Robot("robert") robert.__proto__.constructor // ƒ Robot(name) {this.name = name} roboert.__proto__.constructor.__proto__.constructor // ƒ Function() { [native code] } robert.__proto__.__proto__.constructor // ƒ Object() { [native code] } robert.__proto__.__proto__.constructor.__proto__.constructor // ƒ Function() { [native code] } robert.__proto__.__proto__.__proto__ // null
通过原型链,我们可以知道我们的实例对象源于谁。如上面的例子,我们创建了构造函数 Robot,用它实例化了一个robert对象,所以robert对象源自于构造函数Robot,而构造函数Robot的原型通过打印值,我们知道它源自于对象Function;接着看,通过原型链继承我们可以知道,Robot继承自对象Object,而Object的构造函数则源自于Function;而顺着原型链我们查找Object的原型的对象,会得到一个空值。所以,通过上述的结果,我们发现在js中不管我们是用构造函数创建的对象还是用js本身提供的数据类型创建的对象都源自于Function。
在js中创建对象的基本方式大致分为四类:
构造函数 (如:一般构造函数,寄生构造函数,稳妥构造函数等)
包装器(如:new Number()/new Object()等等)
对象字面量 (如:var obj = {name: "robert", age: 18})
原型
然后,就是根据需要使用上面的基本方式的随机组合。
Function对象的属性Function既然是个对象,那么它就可以拥有自己的属性。这个我们可以在浏览器控制台输入 函数名. 后,浏览器就可以自动提示函数的属性。而我们常用的式函数的内部属性,我们常见的就是 arguments 和 this。前者是一个包含函数传入的参数伪数组,后者指向函数对象本身。同时我们也注意到了arguments对象包含一个属性 callee ,它是一个指针,指向包含 arguments 属性的函数。它和 this 的区别就是arguments.callee()可以代表函数本身,而 this 就是函数执行环境的对象。
使用arguments.callee()可以解除函数体内代码和函数名的耦合状态。
参考代码如下:
function fic(n) { return n <=1 ? 1 : n * arguments.callee(n-1) } function fic2(n) { return n <= 1 ? 1 : n * fic(n-1) } function fic3() { return 0 } fic(5) // 120 fic2(5) // 120 var fic4 = fic var fic5 = fic2 fic = fic3 fic2 = fic3 fic(5) // 0 fic2(5) // 0 fic4(5) // 120 fic5(5) // 0
通过函数fic4和fic5的比较我们可以的出上面的结论。
name: 函数的名字
length: 函数传入参数的个数
Function对象的方法我们常见的是 apply/call , apply方法接收两个参数,第一个都是在其中运行的函数作用域,第二个参数为一个参数数组。
在ES5中还有一个方法bind也可以改变函数运行时内部的作用域,它有一个参数,该参数就是函数内部this要绑定的对象。
后续可能还会继续修改,也欢迎各位批评指正。有问题或者有其他想法的可以在我的GitHub上pr。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/94607.html
摘要:今天同学去面试,做了两道面试题全部做错了,发过来给道典型的面试题前端掘金在界中,开发人员的需求量一直居高不下。 排序算法 -- JavaScript 标准参考教程(alpha) - 前端 - 掘金来自《JavaScript 标准参考教程(alpha)》,by 阮一峰 目录 冒泡排序 简介 算法实现 选择排序 简介 算法实现 ... 图例详解那道 setTimeout 与循环闭包的经典面...
摘要:函数表达式的分类匿名函数表达式具名函数表达式自调用函数表达式函数表达式的用法使用来接偶函数名和函数体的耦合状态。修改函数表达式代码如下闭包我们知道,函数表达式是将匿名函数赋值给一个变量,作为变量的值,所以,匿名函数也可以作为的返回值。 这篇文章要介绍的内容是函数表达,因为我个人比较喜欢使用函数表达式定义函数,所以就对它做了一些研究和整理。其实,说到函数表达式,就不得不说到定义函数的另一...
摘要:责编现代化的方式开发一个图片上传工具前端掘金对于图片上传,大家一定不陌生。之深入事件机制前端掘金事件绑定的方式原生的事件绑定方式有几种想必有很多朋友说种目前,在本人目前的研究中,只有两种半两种半还有半种的且听我道来。 Ajax 与数据传输 - 前端 - 掘金背景 在没有ajax之前,前端与后台传数据都是靠表单传输,使用表单的方法传输数据有一个比较大的问题就是每次提交数据都会刷新页面,用...
摘要:因为用户不用在第一次进入应用时下载所有代码,用户能更快的看到页面并与之交互。译高阶函数利用和来编写更易维护的代码高阶函数可以帮助你增强你的,让你的代码更具有声明性。知道什么时候和怎样使用高阶函数是至关重要的。 Vue 折腾记 - (10) 给axios做个挺靠谱的封装(报错,鉴权,跳转,拦截,提示) 稍微改改都能直接拿来用~~~哟吼吼,哟吼吼..... 如何无痛降低 if else 面...
摘要:插件开发前端掘金作者原文地址译者插件是为应用添加全局功能的一种强大而且简单的方式。提供了与使用掌控异步前端掘金教你使用在行代码内优雅的实现文件分片断点续传。 Vue.js 插件开发 - 前端 - 掘金作者:Joshua Bemenderfer原文地址: creating-custom-plugins译者:jeneser Vue.js插件是为应用添加全局功能的一种强大而且简单的方式。插....
阅读 2932·2023-04-26 01:49
阅读 2065·2021-10-13 09:39
阅读 2278·2021-10-11 11:09
阅读 922·2019-08-30 15:53
阅读 2815·2019-08-30 15:44
阅读 916·2019-08-30 11:12
阅读 2965·2019-08-29 17:17
阅读 2370·2019-08-29 16:57