arguments+原型链+箭头函数+ 作用域+闭包
(1)arguments 是 " 类数组 / 伪数组 " , 本质上是一个对象 , 是 以对象的形式 存储函数调用
时传递的实参
(2)" 伪数组 "是指:
arguments 的 length 表示" 函数调用时实参的个数 "
arguments 可以通过 中括号 加上从0开始的下标 访问函数调用时 传递的 各个实参
(3)arguments[0]( ); 调用时,this指向arguments
arguments.0( ); 两行调用方式一样,但是键值是数字不能用.0的方式调用,只能用[ ]
(4)arguments 有个不常用的属性 callee() , callee() 指向当前函数自身
主要用于匿名函数自己调用自己 ( 主要用于匿名递归函数 )
1 function() { 2 arguments.callee(); 3 }
<!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <title>arguments</title>
6 </head>
7 <body>
8 <!-- 函数中都有一个内置arguments方法。
9 arguments 是[类数组/伪数组]是一个特殊的数组。
10 对象也是是一个特殊的数组
11 arguments.length 表示调用是实参的个数。
12 在arguments 中调用内容
13 ----------------------------------
14 可以是argument[index]调用
15 也可以使用arument.index()。
16 -----------------------------------
17 但是是index是数字是不能进行调用的。所以使用的时候要按照情况进行调用。
18
20 1.当调用arguments的时括号里面就可以省略掉形参
21 案例
22 function neizhi(){
23 console.log(arguments); //不需要形参也可以打印出来
24 }
25 neizhi(5,6,7);
26 2.argument 可以通过中括号加上从0开始的下标访问函数调用时传递的各个参数。 调用的是具体的某一个。
27 案例:
28 function neizhi(){
29 console.log(argument[index])
30 }
31 neizhi(5,6,7);
32
33 3.在函数中显示递归,
34 第一种在函数中调用有名字的函数
35 案例: function neizhi(){
36 neizhi() // 在里面进行自身的函数。
37 }
38 第二种在函数种调用匿名函数。 这个就是argument中不常见的属性叫 callee()
39 案例:function(){
40 argument.callee() 就可以调用 自身这个函数
41 }
42 -->
43 <!-- 面试案例 -->
44 <script type="text/javascript">
45 // var length = 1;
46 // var obj = {
47 // length:100,
48 // fun:function(){
49 // arguments[0]();
50 // // arguments.0();
51 // }
52 // }
53 // obj.fun(function(){
54 // console.log(this.lenght);
55 // },1000)
56
57 // 最后结果时 2. this指的时argument.
58 //
59
// arguments.0(); 两行调用方式一样,但是键值是数字不能用.0的方式调
用,只能用[ ],所以this实际上指向arguments
60 </script>
61 </body>
62 </html>
---------------------------------------------------====================================================================
原型+原型链
1.在讨论原型和原型链,我姑且认为所有的对象或变量都是直接或间接new某一个函数产生的。
2.如果一个变量或对象是直接或间接new某一函数创建的,我们就把被new的函数称为new东西的 ’构造函数‘(就是母亲)
3.构造函数的prototype属性为被new出来的变量或对象的 ’原型/原型对象 ‘。
4.javascript 规定,一个对象或变量的原型/原型对象上所有具有的属性和方法。变量或对象上也自动具有
对原型链进行解释
5.一个变量或对象通过 点调用属性或方法进行调用之前,应该首先先调用一下调用的东西是否存在,
判断方法如下 。JavaScript是判定对错的时候,先看这个变量对象上有没有调用的属性和方法。有就判定正确并且调用,如果没有就去找对象或变量的原型对象。看看原型对象上有没有
要调用的属性和方法。有就判定正确并且调用,如果没有就继续去找原型对象的原型对象,以此类推,直到
找到object.prototype 如果 object.prototype上没有要调用的属性和方法,则判定失败!这个就是原型链
( 因为JavaScript 规定 object.prototype 的原型对象为 null !!!)
null
Object.prototype
{
// 所有的函数的 prototype = new Object();
// 所有的数组 Array.prototype
// 所有的字符串 String.prototype
// 所有的函数 Function.prototype
}
1 (4)JavaScript是如何通过一个变量或对象去查找它的原型对象的? 2 所有的变量或对象都存在一个属性__proto__,这个属性指向了自己的原型对象 3 因为Array.prototype上也有一个__proto__指向自身 4 Array.prototype.__proto__ = Array.prototype; 5 arr.__proto__ => Array.prototype 6 (5)可以通过给原型或原型链添加新的方法来让所有的该原型/原型链的变量或对象具有 7 Array.prototype.aaa = function(){ 8 console.log('这是一个新添加的方法'); 9 } 10 注意:这种写法不可取,会把prototype原有的默认属性和方法全部抵消 11 Array.prototype = { 12 aaa:function(){ 13 console.log('这是一个新添加的方法'); 14 } 15 } 16 (6)如何判断一个变量或对象 arr 是不是一个数组? 17 Object.prototype.toString.call(arr) === "[object Array]" // [object 18 Array] 19 Object.prototype.toString = function() {} 20 Array.prototype.toString = function() {} 21 // arr的父级上也有tostring方法,但是作用不是判断类型 22 // 根据原型链,如果正序调用会被Array的截胡 23 // 所以直接从Object调用,用call()方法强制指向arr
=======================================================================================
箭头函数
(1)、es6里面的 箭头函数
var fun = function(){}; //普通函数
var fun = () =>{} //箭头函数
(2)、箭头函数规定仅有一个参数的时候,可以省略小阔号。
如果函数执行体整体看来只有一行代码时,可以把该行代码的分号,
大括号,return 都声乐
var fun = () =>{
return a>100;
}
可以这个样子写
var fun = a => a>100
3)关于箭头函数是否可以无脑替换普通函数:如果函数中不存在this关键字的使用可以无脑
替换
(4)使用箭头函数之后this指向谁
如果函数中使用了this关键字,改成箭头函数后,箭头函数中的this会穿透指向父级
作用域中的this
函数如果是以箭头函数创建,this关键字永远指向该函数的父级作用域
函数创建完内部this就已经永远绑死,后续再怎么call都无法改变this指向!!!
================================================================================
作用域:
(1)为什么要知道作用域?
为了能够准确的判断var声明的变量的生命周期,为了判定函数的生命周期
(2)全局作用域 函数作用域
全局:在全局作用域中 声明创建的 变量和函数 为全局变量和全局函数
局部:在函数作用域中 声明创建的 变量和函数 为局部变量和局部函数
【注1】函数中 局部变量 如果和 全局变量 重名 则会 屏蔽掉 全局变量
【注2】函数的 形参 也算是 函数的 局部变量
(3)代码的执行过程:任何一段js代码在执行前都会先预编译,再执行
(4)预编译:会把马上要执行的代码中的变量声明进行提前(赋值不提前),再把函数声明进行
提前
匿名函数 var fun = function() { }; 不会预编译,只有标准函数声明才会预编译
(6.)函数的作用域链
函数声明完成,则其对应发然 作用域链 已经确立
同样在 函数声明的内部 进行调用的时候,先从最近的及逆行判断。
1.全局作用域之外,每个函数都会创建自己的作用域,作用域在函数定义时就已经确定了,而不是在函数调用时确定的。
2.全局执行上下文环境是在全局作用域确定之后,js代码马上执行之前创建。
3.函数执行上下文环境是在调用函数时,函数体代码执行之前创建。
区别:
作用域是静态的,只要函数定义好了就一直存在,且不会再变化。
上下文环境是动态的,调用函数时创建,函数调用结束时上下文环境就会被释放。
面试会出的题:页面中存在五个按钮,请绑定点击事件,分别弹出01234
var btns = null;
for( var i=0;i<btns.length;i++ ){
(function(i){
btns[i].onclick = function(){
console.log(i);
};
})(i) // 闭包
}
(6)闭包:自己调用自己 IIFE 立即调用函数表达式
控制内部局部变量的生命周期,让内部的函数能闭包到这个局部变量
===============================================================================
闭包:

浙公网安备 33010602011771号