JS相关知识学习笔记(三)

2021-05-20  本文已影响0人  喑宝儿
1、函数的定义

(1)命名函数

function fn() {}

(2)函数表达式(匿名函数)

var fun = function() {}

(3)new Function('参数1', '参数2', 函数体)

var f = function('a', 'b', 'console.log(a + b)')
f(1, 2)  // 3

new Function()的参数必须都是字符串

所有的函数都是Function的实例(对象)

函数本质上也是对象

2、函数的调用方式以及this指向问题(一般都指向调用者)

(1)普通函数

function fn() {}
// 调用
fn() // this指向window
fn.call() // this指向window

(2)对象的方法

var o = {
    say: function() {}
}
// 调用
o.say()  // this指向o

(3)构造函数

function Person() {}
Person.prototype.say = function() {}
// 调用
var p = new Person()  // 构造函数和原型对象中的this都指向p这个实例对象

(4)绑定事件函数(点击按钮即可调用)

btn.onclick = function() {
  console.log(this)  // this指向btn
}

(5)定时器函数(定时器隔特定时间自己调用)

setInterval(function() {  
  console.log(this)  // this指向window
}, 1000)

(6)立即执行函数(自动调用)

(function() { 
  console.log(this)  // this指向window
})()
3、修改函数内部的this指向

(1)call(this的指向, 参数1, 参数2, …)

可以调用函数传递参数,改变this的指向,也可以实现继承

var o = {name: 'zs'}
function sum(a, b) {
  console.log(this)  // this指向o对象
  console.log(a + b)  // 3
}
sum.call(o, 1, 2)

(2)apply(this的指向, [数组])

可以调用函数传递参数,改变this的指向,参数必须是数组,否则会报错

apply的主要应用:借助数学内置对象求最大值,使用时最好让apply的this指向Math

var o = {name: 'zs'}
function sum(arr) {
  console.log(this)  // this指向o对象
  console.log(arr)  // ls
}
sum.apply(o, ['ls'])

var arr = [23, 43, 51, 12, 26]
var max = Math.max.apply(Math, arr)
console.log(max)  // 51

(3)bind(this的指向, 参数1, 参数2, …)

bind仅仅是返回一个新函数,把this指向修改为指定的对象,依次传递参数

原函数不会被更改

var o = {name: 'zs'}
function sum(a, b) {
  console.log(this)
  console.log(a + b)
}

var newF = sum.bind(o, 1, 2)
newF(3, 4)  // 打印o   打印3  //按顺序传,传的1, 2——1+2=3

var newFn = sum.bind(o)
newFn(3, 4)  //打印o   打印7  // 按顺序传,传的3, 4——3+4=7

var newFnn = sum.bind(o, 1)
newFnn(3, 4)  //打印o   打印4  // 按顺序传,传的1, 3——1+3=4

var newFnnn = sum.bind(o, 1)
newFnnn()  //打印o   打印NaN  // 按顺序传,传的1——1+undefined=NaN

如果有的函数不需要立即调用,但是又想改变this的指向可以使用bind,比如改变定时器中的this指向

var btn = document.querySelector('button')

btn.onclick = function() {
    this.disabled = true
    setTimeout(function() {
        this.disabled = false
    }.bind(this), 3000)
}

bind进行函数参数的替换或者保存一些要使用到的值(下面要求弹出每一个li的索引值)

<ul>
   <li>1</li>
   <li>2</li>
   <li>3</li>
   <li>4</li>
</ul>
<script>
  var lis = document.querySelectorAll('li')
  for (var i = 0; i < lis.length; i++) {
    lis[i].onclick = function(index) {
      alert(index)  // 直接弹出i则是for运行完最后的i
    }.bind(lis[i], i)  // 此处将函数的参数index替换为每一次循环的i,每点击一个li,弹出相对应的索引
  }
</script>

如果不想改变函数内部的this指向,又想要在函数内部使用到外部的this,在不需要牺牲空间的情况下(即不需要使用全局变量that保存外部this了),可以使用bind将this指向设置为函数,将外部的this当作参数传递给函数

4、严格模式(ES5新增,IE10以下有兼容性问题,会忽略严格模式)

(1)为脚本开启严格模式

<script>
  'use strict'
</script>

<script>
  (function() {
    'use strict'
    })()
</script>

(2)为某个函数开启严格模式

<script>
  function fn() {
    'use strict'  // 只为此函数开启严格模式
  }
  function f() {}
</script>

(3)严格模式的特点

1、变量必须先声明再使用,且随意删除已经声明好的变量

2、严格模式下的全局作用域中,this指向undefined,而不是window

3、严格模式下,构造函数不加new调用时,this会报错,实例化的构造函数还是指向创建的实例对象

4、定时器this指向的还是window

5、事件、对象的this还是指向调用者

6、函数的参数不可以同名

7、不可以在非函数代码块中定义函数(即:不可以在函数之外的{}中定义函数),比如:if,for等,函数中是可以嵌套函数的

5、高阶函数
6、闭包

闭包:有权访问另一个函数作用域中变量的 函数或者代码使用方式(现象)

闭包的主要作用:延伸了变量的作用范围

function fn() {
  var num = 10
    return function(n) {
    console.log(n + num)
  }
}
var fun = fn()
fun(4)  // 14 即4+10,访问到了num,产生了闭包fn(变量所在的函数)
上一篇下一篇

猜你喜欢

热点阅读