目录
函数的三种调用方式(this指向)
复习函数三种调用方式:普通函数 对象方法 构造函数
-
重点:理解this关键字作用:
谁调用这个函数,this指向谁
-
函数三种执行模式 : 全局函数 、 对象方法 、 构造函数
this : 谁 `调用` 我,我就指向谁
1. 全局函数 : this指向window
2. 对象方法 : this指向对象
3. 构造函数 : this指向new创建的空对象
<script>
/**1.this环境对象,谁调用我就指向谁
重点:函数与声明无关 取决于函数调用
1 普通函数调用, 函数名() this指向window
2 对象方法调用 对象名.方法名() this指向对象
3 构造函数调用 new 函数名() this指向new创建的实例对象
2.分析this指向心得,this指向取决于函数的调用 而函数有三种调用方式 所以this指向也会有三种方式
1 优先用排除法分析,如果有new关键字 则指向nwe创建对象 否则不是window就是对象
2 如果判断this是window还是对象,就看调用是函数名()还是对象名.方法名()
*/
</script>
函数执行的上下文模式
call() apply() bind()
异同点
-
相同之处:都可以修改函数中this指向
-
不同点:传参方式不同
-
call()语法:
函数名.call(this修改后的指向,arg1,arg2…………)
-
apply()语法:
函数名.apply(this修改之后的指向,伪数组或者数组)
-
bind()语法:
函数名.bind(this修改后的指向,arg1,arg2....)
-
bind()语法并不会立即执行函数,而是返回一个修改指向后的新函数,常用于回调函数
-
-
Call()
<script>
/**1.this环境对象,谁调用我就指向谁
重点:函数与声明无关 取决于函数调用
1 普通函数调用, 函数名() this指向window
2 对象方法调用 对象名.方法名() this指向对象
3 构造函数调用 new 函数名() this指向new创建的实例对象
2.分析this指向心得,this指向取决于函数的调用 而函数有三种调用方式 所以this指向也会有三种方式
1 优先用排除法分析,如果有new关键字 则指向nwe创建对象 否则不是window就是对象
2 如果判断this是window还是对象,就看调用是函数名()还是对象名.方法名()
*/
/**
1.默认情况下. this指向是无法修改的
* 1 普通函数调用, 函数名() this指向window
2 对象方法调用 对象名.方法名() this指向对象
3 构造函数调用 new 函数名() this指向new创建的实例对象
2.上下文调用: 修改函数中this指向
(1)函数名.call(修改的this,参数 1,参数2.....)
(2) 函数名.apply()
(3)函数名.bind(修改的this)
*bind不会立即调用函数,而是得到一个修改后的新函数
经典面试题,请说说call,apply,bind有什么区别
*/
function fn(a, b) {
console.log(this)
console.log(a, b)
}
fn(1, 2) // 这个this指向window
fn.call({
name: '聪明蛋'
}, 10, 20)
//函数名.call(修改的this,参数 1,参数2.....)
// call 场景 : 数据类型检测
//1.typeof 数据 :检测数据类型
/**
* typeof 有两种数据类型无法检测:null.array 都会得到object
*/
console.log(typeof 123) // number
console.log(typeof '123') // string
console.log(typeof true) //boolean
console.log(typeof false) //boolean
console.log(typeof undefined) //undefined
console.log(typeof null) //object
console.log(typeof [10, 20, 30]) //object
console.log(typeof
function () {}) //function
console.log(typeof {
name: '聪明蛋'
}) //object
// 2.object.prototype.toString():得到固定格式字符串
// "[object.type]",其中的type 是对象
// 检测数据类型固定语法:object.prototype.toString.call(数据)
console.log(object.prototype.toString.call(123)) //[object Number]
console.log(object.prototype.toString.call('123')) //[object String]
console.log(object.prototype.toString.call(true)) //[object Boolean]
console.log(object.prototype.toString.call(undefined)) //[object Undefined]
console.log(object.prototype.toString.call(null)) //[object Null]
console.log(object.prototype.toString.call([12, 123, 123, ])) //[object Array]
console.log(object.prototype.toString.call(function () {})) // [object Function]
console.log(object.prototype.toString.call({
name: '聪明蛋'
})) // [object Object]
</script>
apply()
function fn(a, b) {
console.log(this)
console.log(a, b)
}
//call传参需要一个一个传,一般用于修改单个参数的函数this
fn.call({
name: '张三'
}, 10, 20)
//apply传参通过数组来传.一般用于修改多个参数的函数this
fn.apply({
name: '李四'
}, [30, 40])
bind()
function fn(a, b) {
console.log(this)
console.log(a, b)
}
//call传参需要一个一个传,一般用于修改单个参数的函数this
fn.call({
name: '张三'
}, 10, 20)
//apply传参通过数组来传.一般用于修改多个参数的函数this
fn.apply({
name: '李四'
}, [30, 40])
// bind不会立即调用函数,而是得到一个修改后的新函数
fn.bind({
name: '王五'
})
递归
递归函数介绍
-
1.递归函数:一个函数自己调用自己
-
2.递归函数特点
-
a.一定要有结束条件,否则会导致死循环
-
b.能用递归函数实现的需求,就一定可以用循环调用函数来解决,只是代码简洁与性能不同而已
-
<script>
let num = 1
while(num<=3){
console.log('聪明蛋最好看')
num++
}
let i = 1
function fn() {
if (i <= 3) {
console.log('聪明蛋最漂亮')
i++
fn()
}
}
fn()
</script>
闭包(closure)
闭包的定义
-
1.闭包 : 是一个可以访问其他函数作用域的函数
-
2.闭包 = 函数 + 上下文的引用,闭包不等于函数。以下代码就构成了闭包:
-
闭包的作用
直接作用:解决变量污染问题,让变量被函数保护起来。
闭包小结
-
闭包 = 函数 + 上下文的引用
-
闭包的作用:解决变量污染问题,让变量被函数保护起来。
-
在 ES5 时代,闭包可以解决一些其他 JavaScript 的小 BUG,但随着 ES6
let
等新语法的诞生,之前一些闭包的使用场景已经不再需要,后续在就业课中会讲,帮助大家突击面试。
-