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 立即调用函数表达式

控制内部局部变量的生命周期,让内部的函数能闭包到这个局部变量

===============================================================================

闭包:

 

 

posted @ 2020-12-07 10:41  诗亦0615  阅读(251)  评论(0)    收藏  举报