函数怎么调用

如果是数据,就是直接用的。比如 n = 1,要用就直接写上 n 就可以了。而函数要用的话叫做 调用,英文 call 或者 invoke。那函数是怎么调用的了?比如

function f(x,y) {return x+y}

函数 f 怎么调用了?

首先我们看,函数到底是什么?

函数是一段可以反复调用的代码块

比如,我们求三角形的面积,我们知道它的宽为 100、高为 200。三角形面积公式为 S = ah/2。所以结果为 100 x 200 / 2 = 10000。JavaScript 代码写下来:

width = 100
height = 200
var area = width * height / 2
area // 10000

那上面的 var area = width * height / 2 以及返回 area 就是求三角形面积的两句话,那我们可以把这两句话写成一个函数,然后取一个名字。比如说:

function 求三角形面积(w,h) {
var area = w * h / 2
return area
}
求三角形面积(4,3) // 6
求三角形面积(5,3) // 7.5

求三角形面积 这个函数就可以反复调用。

函数在内存中是怎么存的?

函数在内存里面是存的函数 toString 值。实际上是一个字符串。

function f(x,y){return x+y} 改用更明确的形式 var f = new Function('x', 'y', 'return x+y')

在栈中存入 f,值为 ADDR 77,然后在堆中有一个 ADDR 77 的值,它里面对应存了函数的参数,比如 params:['x', 'y'],然后还有函数体 fbody:'return x+y',然后就是函数的共有属性 __proto__。而 __proto__ 里面有个方法叫 call,call 调用 fbody

memory

这个调用的过程:

var f = {}
f.name = f
f.params = ['x', 'y']
f.fbody = 'console.log(1)'
f.call = function() {
window.eval(f.body)
}
// 调用
f.call()
// 1

函数是一个对象,因为函数的调用过程,其实就是 eval 它的函数体的过程。

eval 的参数是字符串,eval 执行它的参数。

所以可以总结为:可以执行代码的对象叫做函数。

硬核玩家函数调用

function f(x,y) {return x+y}
f.call(undefined, 1, 2) // 3

知识体系回顾

JavaScript 有 7 种数据类型:number,string,boolean,null,undefined,symbol,object

最复杂的就是 object 它是复杂对象,它能包含其他数据类型。

比如一个普通对象 {name: ‘frank’},它有个 toString 方法,继承自它的 __proto____proto__指向 Object.prototype。还有一个 Array.prototype 的原型,比如我们有个数组 [1,2,3],它有个__proto__ ,它是指向 Array.prototype,它有 push,pop 等方法。然后有个 Function.prototype 的原型,比如我们有个函数 var f = function(){},它有个__proto__,它指向 Function.prototype,它里面有 bind、call、apply 方法。

其他

var a = 1,2 // 报错
var a = (1,2) // 2