JavaScript高级第二天
1.函数定义和调用
//普通函数 this指向window
function fn() {
console.log(this)
}
fn();
fn.call();
// 对象的方法 this指向实例对象原型对象里面的方法也指向实例对象
var o = {
sing: function () {
console.log(this);
},
};
o.sing();
// 构造函数 该访法所属对象
function Star() {}
new Star();
// 绑定事件 绑定事件对象
// btn.noclick =function() {}//通过点击事件
// 定时器调用 window
// setTimeout(function() {},2000) //会自动调用
// 立即执行函数 window
// (function(){})()自动执行
2.this指向
这些this的指向,是当我们调用函数的时候确定的。调用方式的不同决定了this的指向不同
一般指向我们的调用者.
调用方式 this指向
普通函数调用 window
构造函数调用 实例对象原型对象里面的方法也指向实例对象
对象方法调用 该访法所属对象
事件绑定方法 绑定事件对象
定时器函数 window
立即执行函数 window
3.改变this指向的方法
1.call方法
call()可以改变this的指向
function all (a,b){
console.log(this)
console.log(a+b)
}
var o = {
name: "and"
}
all(3,4)
//call()可以改变this的指向 这里让他指向o
all.call(o,5,3)
借用父结构函数
1.传值
function Father(uname,password){
this.uname =uname
this.password = password
}
function Son (uname,password){
//父级调用call 让父级的this 指向sub的this
Father.call(this,uname,password)
}
var son =new Son('ldh',123456)
console.log(son.password)
2.传方法
//让子类的prototype 指向一个新的构造函数(Father)
Son.prototype = new Father( );
//如果利用对象的形式修改了原型对象,别忘了利用constructor指回原来的构造函数
Son.prototype.constructor = Son;
2.apply方法
var o ={
username: "andi"
}
function fn (uname){
console.log(uname)//张三
console.log(this)
}
fn.apply(o,['张三'])
//1.也是调用函数第二个可以改变函数内部的this指向 //2.但是他的参数必须是数组(伪数组) // 3. apply 的主要应用比如说我们可以利用apply 借助于数学内置对象求最大值 // Math. max();
var arr =[1,5,3,2,66,3,2,444,2]
//因为apply传的是数组 但解析出来的是数字型 所以可以使用Math方法
var max = Math.max.apply(Math,arr)
console.log(max)
3.bind方法
var o ={
username: "andi"
}
function fn (a,b){
console.log(a+b)
console.log(this)
}
//不会执行 因为他是返回一个新的对象
//fn.bind(o,1,2)
var f =fn.bind(o,1,2)
f()
-
不会调用原来的函数 可以改变this指向
-
返回的是原函数改变this之后产生的新函数
-
如果有一个函数不需要立即调用 ,但是又想改变里面this的指向就可以用bind
- 例如点击按钮后三秒禁用后重新可以执行
var btn =document.querySelector('button') btn.onclick = function() { console.log('aaaa') // 点击禁用 this.disabled=true // 三秒后重新开启 setInterval(function(){ this.disabled = false }.bind(this),1000) }
4.call apply bind总结
相同点: . 都可以改变函数内部的this指向. 区别点:
-
call和apply会调用函数,并且改变函数内部this指向.
-
call 和apply传递的参数不一样, call传递参数aru1, aru2..形式apply必须数组形式[arg]
-
bind 不会调用函数,可以改变函数内部this指向.
主要应用场景:
1.call经常做继承.
2.apply 经常跟数组有关系.比如借助于数学对象实现数组最大值最小值
3.bind 不调用函数但是还想改变this指向.比如改变定时器内部的this指向.
4.严格模式
严格模式就是规范代码
//全部的严格模式
<script>
'use strict'
</script>
//立即执行的严格模式
<script>
(function(){
'use strict'
})()
</script>
//单个函数进行严格模式
function fn(){
'use strict'
}
5.高阶函数
高阶函数就是 接受的参数是一个函数 或者 返回值是一个函数
function fn(a,b,callback){
console.log(a+b)
callback && callback()
}
// 接受的参数是一个函数
fn(1,4,function(){
console.log('我是高阶函数')
});
//返回值是一个函数
function fn1(){
return function(){
}
}
fn1()
6.什么是闭包
//闭包(closure)指有权访问另一个函数作用域中变量的函数。 //一个作用域可以访问另外一个函数的局部变量 //我们fn外面的作用域可以访问fn内部的局部变量 优点 //闭包的主要作用:延伸了变量的作用范围 缺点 如果一直使用内部函数的变量导致不会销毁从而导致内存泄露 解决 用完这个变量把他设置成null
应用场景有防抖节流 防抖存定时器的id 可以清除定时器 节流存储默认开关 达到什么时候关什么时候开
function fn(){
var num = 10
// 返回一个函数 (就是高阶函数)
// 返回一个函数带着num的值
return function fn1(){
console.log(num)
}
}
// 通过调用fn把返回值赋值给f 这个f也是个函数所以能够调用
var f = fn()
f()
7.什么是递归
递归就是自己调用自己
记住一定要用return 退出循环
// 利用递归的阶层1~n的阶层 n*....5*4*3*2*1
function fn(n){
// 如果没遇到1就继续执行
if (n==1){
return 1
}
// n * fn(n-1) 一直重新调用
return n * fn(n-1)
}
fn()
8.深拷贝浅拷贝
浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用. 深拷贝拷贝多层,每一级别的数据都会拷贝. Object.assign( target, ... sources) es6 新增方法可以浅拷贝
Object.assign(拷贝到的地方,拷贝源) //浅拷贝 如果有对象的只是拷贝了对象的地址
深拷贝