function 类型

原创 里羊羊羊 随笔 javascript 学习随笔 154阅读 2017-11-22 17:57:58 举报

函数

函数实际是对象。每个函数都是Function类型的实例,具有属性和方法。函数名是一个指向函数对象的指针;

javascript 代码

严格模式对函数有一些限制:

不能把函数命名为 eval 或 arguments;
不能把参数命名为 eval 或 arguments;
不能出现两个命名参数同名的情况
否则会导致语法错误,代码无法执行
位于return之后的代码永远不会执行

参数

ECMAScript函数不介意传递进来多少个参数,也不在乎传递进来参数是什么数据类型;(即便定义的函数只接收两个参数,在调用的时候可以传递一个、两个、三个甚至不传递参数)

在函数体内部可以使用 arguments 对象访问参数数组,从而获得传递给函数的每一个参数 arguments 对象只是与数组类似(并不是array实例),可以使用 [ ]访问它的每一个元素,可以使用length 属性确定传递进来的参数个数;

javascript 代码

执行环境

定义了变量或函数有权访问的其他数据,决定了他们个子的行为; 每个执行环境中都有一个与之关联的变量对象,环境中定义的所有函数和变量都保存在这个对象中;
某个执行环境中的所有代码执行完毕后改环境被销毁,保存在其中的变量和函数定义也销毁;全局执行变量直到应用程序退出才会销毁(比如关闭网页或浏览器)

每个函数都有自己的执行环境。当函数执行时,函数的执行环境会被推入一个环境栈中,执行后,栈将其环境弹出,把控制权返回给之前的执行环境。

当代码在一个环境中执行时,会创建变量对象的一个作用域链;其用途是保证对执行环境有权访问的所有变量和函数的有序访问; 每次进入一个新执行环境时,都会创建一个用于搜索变量和函数的作用域链; 标识符解析是沿着作用域链一级一级搜索标识符的过程。

使用 var 声明的变量会自动添加到最接近的环境中 如果初始话变量没用var,该变量会自动添加到全局变量

作用域链

javascript 代码

最后打印出来的是3,因为执行函数c()的时候它在自己的范围内找到了变量a所以就不会越上继续查找,如果在函数c()中没有找到则会继续向上找,一直会找到全局变量a,这个查找的过程就叫作用域链,作用域只会向上查找。

没有块级作用域

原型链

创建函数时,会自动为函数添加一个prototype属性,该属性指向一个对象引用,这个对象称为原型对象。默认情况下该对象只包含一个constructor属性,它是一个指向prototype属性所在函数的指针; 原型对象包含函数实例共享的方法和属性,也就是说将函数用作构造函数调用(使用new操作符调用)的时候,新创建的对象会从原型对象上继承属性和方法。Javascript的继承机制基于原型。

当我们调用该函数作为构造函数创建一个实例时,该实例将存在一个内部属性proto,它是一个指针指向改函数的原型指针

hasOwnProperty
javascript中唯一一个处理属性但不查找原型链的函数

javascript 代码

js上下文

函数声明和函数表达式

//函数声明
function say(){
console.log('hello')
}

//函数表达式
var say=function (){
console.log('hello')
}
变量、函数声明提升

每当调用一个函数时,一个新的执行上下文就会被创建出来。在javascript 引擎内部这个上下文创建的过程有两个阶段:

建立阶段(发生在调用一个函数时,但是在执行函数体内的具体代码之前)
建立变量,函数,arguments对象,参数(变量、函数声明提升)
建立作用域链
确定this值
代码执行阶段
变量赋值,函数引用,执行其他代码

变量声明提升: 通过 var声明的变量在代码执行之前被js引擎提升到了当前作用域的顶部。
函数声明提升: 通过函数声明的方式(非函数表达式)声明的函数在代码执行之前被js引擎提升到了当前作用域的顶部,而且函数声明提升优先于变量声明提升。
提升规则

预解析的顺序是从上到下,函数的优先级高于变量,函数声明提前到当前作用域最顶端,在var之上。
函数执行的时候,函数内部才会进行预解析,如果有参数,先给实参赋值再进行函数内部的预解析。
预解析函数是声明+定义(开辟了内存空间,形参值默认是undefined)。
预解析变量是只声明,不赋值,默认为undefined。
函数重名时,后者会覆盖前者。
变量重名时,不会重新声明,但是执行代码的时候会重新赋值。
变量和函数重名的时候,函数的优先级高于变量。
javascript 代码

作为值的函数

访问函数指针而不是执行函数时必须去掉函数名后面的括号
javascript 代码

函数属性和方法

属性:length和prototype

length属性表示函数希望接收的命名参数的个数;
prototype

call和applay

call和applay(每个函数都有非继承而来的函数) 在特定的作用域中调用函数,实际上等于设置函数体内this对象值。

applay() 方法接收两个参数,一个是在其中运行函数的作用域,另一个是参数数组。其中第二个参数可以是Array的实例,也可以是arguments对象。

call() 第一个参数是this值,而传递给函数的参数必须逐个列举出来

javascript 代码

它们真正强大的地方是能够扩充函数作用域。
ECMAScript 还定义了一个方法:bind()。该方法建立一个函数实例,其this值会被绑定到传给bind()函数的值

javascript 代码

函数内部属性和方法

函数内部有两个特殊对象 arguments和 this;其中arguments包含传入函数中的所有参数

callee

函数arguments有一个名叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数。
严格模式下访问arguments.callee会报错
ECMAscript还定义了arguments.caller 该属性在严格模式下会错误,严格模式下是undefined。定义该属性是为了区分arguments.caller和函数的caller属性

javascript 代码

caller

caller是函数对象的一个属性。该属性中保存着调用当前函数的函数的引用,如果是在全局作用域中调用当前函数,它的值是null 严格模式下不能为函数的caller赋值,否则会导致错误

javascript 代码

自学笔记,如果有什么不对的地方,请各位大神多多指教

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复