js函数集合

函数

定义、调用、arguments
/**
 * 函数定义
 * 命名函数
 * 函数表达式
 * 构造函数:var 函数名 = new Function(形参1,形参2,函数体)
 * 【注】所有函数都是通过new Function构造出来,都是'function实例',都是实例对象,也属于对象
 */
function test() {
  console.log('hello world')
}
console.log(typeof test) //function
function add(a, b) {
  return a + b
}
var addSum = function (x, y) {
  return x + y
}
var addFun = new Function('a', 'b', 'return a+b')
console.log(add(1, 2)) //3
console.log(addSum(1, 2)) //3
console.log(addFun(1, 2)) //3
console.log(test.__proto__ === Function.prototype) //true
console.log(test instanceof Object) //true
/**
 * 函数调用
 */
// 普通函数
function Fun1() {
  console.log('hello')
}
Fun1() //hello
Fun1.call() //hello
// 通过对象的方法调用
var obj = {
  a: 1,
  b: function () {
    console.log(this.a)
  },
}
obj.b() //1
// 立即执行函数
;(function () {
  console.log('立即执行')
})()
// 通过构造函数来调用(用少)
function Fun2() {
  console.log('constructor function')
}
new Fun2()
// 绑定操作函数
// btn.onClick = function () {
//   console.log(index)
// }
// 定时器函数
// setTimeout(() => {
//   console.log('settimeout')
// }, 1000)
/**
 * 类数组
 * 每次调用函数,都会传递:
 *  函数的上下文对象this
 *  封装函数实参的对象arguments
 * 所有函数都内置有arguments对象,只有函数才有arguments
 * 用途:当不确定有多少参数传递的时候,可以使用arguments
 */
function demo(a, b) {
  console.log(arguments) //[Arguments] { '0': 1, '1': 2, '2': 3 }
  console.log(demo.length) //2 -- 形参个数
  console.log(arguments.length) //3 -- 实参个数
  console.log(arguments.callee == demo) //true -- 返回正在执行的函数
  // arguments是伪数组,可以修改元素,但不能改变数组长度
  arguments[0] = 99
  // arguments.push(8) 报错
}
demo(1, 2, 3)
// 不确定参数多少实例
function maxValue() {
  var flagNum = arguments[0]
  for (var i = 0; i < arguments.length; i++) {
    if (flagNum < arguments[i]) {
      flagNum = arguments[i]
    }
  }
  return flagNum
}
console.log(maxValue(2, 4, 3, 1, 6, 7, 4)) //7
作用域、变量提升
/**
 * 作用域
 * 全局作用域 -- 页面(浏览器)打开时创建,页面(浏览器)关闭时销毁
 * 局部作用域 -- 当其所在代码块运行结束,销毁
 * 作用域上下级关系(作用域链) -- 采用链式查询,就近原则,先在自身作用域中寻找,有就直接使用;没有就向上一级作用域寻找,直到全局作用域,如果全局作用域没有定义,则报错ReferenceError
 */
var a = 'aaa'
function show() {
  var b = 'bbb'
  console.log(a)
}
show() //aaa
// console.log(b) 报错--b is not defined
/**
 * 变量提升 -- 使用var声明的变量,会在所有代码执行之前被声明
 * 【注】没有var声明的变量是全局变量,不会提前声明
 * 定义形参就相当于在函数作用域中声明了变量
 */
console.log(num1) //undefined
var num1 = 10
// console.log(num2) 报错 -- num2 is not defind
num2 = 10
num3 = 10
console.log(num3) //10 -- 相当于 window.num3
/**
 * 函数声明提前
 */
// 使用 函数声明 的方式创建函数,声明会被提前
fun1() //function one
function fun1() {
  console.log('function one')
}
// 使用 函数表达式 的方式创建的函数,声明不会提前
// fun2() 报错 -- fun2 is not defind
var fun2 = function () {
  console.log('function two')
}
fun3() //undefined
function fun3(e) {
  console.log(e)
}
预编译
/**
 * 预编译
 * js :语法分析 -- 预编译 -- 解析执行
 */
function foo() {
  var a = (b = 200)
}
foo()
console.log(b) //200
console.log(window.b) //200
// console.log(a) //Uncaught ReferenceError: a is not defined -- a的作用域仅限于函数内部,不属于window
console.log(window.a) //undefined -- 因为没有var声明的变量为window

// a预编译解析 -- 1 -- 666 -- f a(){} -- 提升全局,最先打印
function baz(a) {
  console.log(a) //f a(){}
  var a = 666
  console.log(a) //666
  function a() {}
  console.log(a) //666
  function b() {}
  console.log(b) //f b(){}
}
baz(1)
this 指向 + call/apply/bind
/**
 * 函数中this指向
 * 以函数(包括普通函数、定时器函数、立即执行函数)的形式调用时,this永远指向window
 * 以方法的形式调用,this指向调用方法的那个对象
 * 以构造函数的形式调用,this指向实例对象
 * 以事件绑定的形式调用,this指向绑定事件的对象
 * 使用call,apply,bind调用,this指向指定对象
 * 箭头函数中的this,指向函数定义时的this,非执行时的this
 */
function fun1() {
  console.log(this) //window
}
fun1()
setTimeout(function () {
  console.log(this) //window
}, 0)
;(function () {
  console.log(this) //window
})()
var obj = {
  name: 'falcon',
  showName() {
    console.log(this)
  },
}
obj.showName() //{name: "falcon", showName: ƒ}
function fun2() {
  console.log(this) //fun2 {}
}
new fun2()
/**
 * fn.call(this指向,函数实参1,函数实参2)
 *  可以调用一个函数,改变这个函数内部this指向
 *  可以实现继承
 * apply
 *  可以调用一个函数,改变这个函数内部this指向
 *  需要传递数组
 * bind
 *  可以调用一个函数,改变这个函数内部this指向
 *  不会立即调用函数
 */
// call - this指向
var obj = {
  name: 'falcon',
  age: 21,
}
function fun1(a, b) {
  console.log(this) //obj
  console.log(this.name) //falcon
  console.log(a + b) //3
}
fun1.call(obj, 1, 2)
// call - 继承
function father(myName, myAge) {
  this.name = myName
  this.age = myAge
}
function son(myName, myAge) {
  father.call(this, myName, myAge)
}
var son1 = new son('jerry', 18)
console.log(son1) //son { name: 'jerry', age: 18 }
// apply - this
var obj1 = {
  name: 'alice',
  age: 23,
}
function fun2(a, b, c) {
  console.log(this.name) //alice
  console.log(a + '+' + b + '+' + c + '=' + (a + b + c)) //1+2+3=6
}
fun2.apply(obj1, [1, 2, 3])
// apply - 应用:求数组中最值
var arr = [2, 4, 6, 3, 5, 7, 1]
console.log(Math.max.apply(null, arr)) //7
console.log(Math.min.apply(null, arr)) //1
// bind - 调用
var obj3 = {
  id: 1,
  lesson: 'Chinese',
}
function fun3(a, b) {
  console.log(this.id) //1
  console.log(a * b) //6
}
fun3.bind(obj3, 2, 3)()
// 手写实现call
Function.prototype.myCall = function (context, ...args) {
  if (typeof this !== 'function') {
    throw new TypeError('It must be a function')
  }
  if (!context) {
    context = window
  }

  const fn = Symbol()
  context[fn] = this
  const result = context[fn](...args)
  delete context[fn]
  return result
}
fun1.myCall(obj, 1, 5)
// 手写实现apply
Function.prototype.myApply = function (context, args = []) {
  if (typeof this !== 'function') {
    throw new TypeError('It must be a function')
  }
  if (!context) {
    context = window
  }

  const fn = Symbol()
  context[fn] = this
  const result = context[fn](...args)
  delete context[fn]
  return result
}
console.log(Math.max.myApply(null, arr))
// 手写实现bind
Function.prototype.myBind = function (context, ...args) {
  const fn = this
  if (typeof fn !== 'function') {
    throw new TypeError('It must be a function')
  }
  if (!context) {
    context = window
  }
  return function (...otherArgs) {
    return fn.apply(context, [...args, ...otherArgs])
  }
}
fun3.myBind(obj3, 3, 3)()
高阶函数+闭包
/**
 * 高阶函数 -- 对其他函数进行操作的函数
 */
// 高阶1 - 把其他函数作为参数
function fun1(a, b, callback) {
  console.log(a + b) //5
  callback && callback() //callback function
}
fun1(2, 3, function () {
  console.log('callback function')
})
// 高阶2 - 把其他区函数作为返回值(闭包)
/**
 * 函数内部可以访问局部和全局
 * 函数外部只能访问全局不能局部
 * 闭包就是有权访问另一个函数中作用域的函数(全局访问局部)
 */
function fun2() {
  var a = 20
  return function () {
    console.log(a)
  }
}
var res = fun2()
res() //20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值