01. this的典型应用场景

this在各个场景中取什么值,是在函数执行的时候确认的,不是在定义的时候确认的。

  • 普通函数执行 返回window
function fn1() {
console.log(this)
}
fn1() // window
  • 使用 call apply 传入什么绑定什么
//call/bind可以改变this指向
function fn1() {
console.log(this)
}
fn1.call({x:100}) //{x:100}
const fn2 = fn1.bind({x:200})
fn2() //{x:200}
  • 作为对象方法执行 返回对象本身
const zhangsan = {
name: '张三',
sayHi() {
// this 即当前对象
console.log(this)
},
wait() {
setTimeout(function(){
// setTimeout本身触发的执行,所以this即是window
console.log(this)
})
}
}
  • 箭头函数方法执行

箭头函数永远是取他上级作用域的this

const zhangsan = {
name: '张三',
sayHi() {
// this 即当前对象
console.log(this)
},
wait() {
setTimeout(() => {
// 箭头函数永远是取他上级作用域的this
console.log(this)
})
}
}
  • class中的值 返回当前实例本身
class People {
constructor(name) {
// 正在创建的实例
this.name = name
this.age = 30
}
sayHi() {
//张三的实例
console.log(this)
}
}
const zhangsan = new People('张三')
zhangsan.sayHi() //zhangsan对象
02. this的具体使用
  • 在html元素事件属性中使用
<input type="button" onclick="showInfo(this)" value="点击一下"/>
  • 构造函数
function Animal(name,color) {
this.name = name;
this.color = color;
}
  • input点击,获取值
<input type="button" id="text" value="点击一下">
<script type="text/javascript">
var btn = document.getElementById("text")
btn.onclick = function() {
alert(this.value); //此处的this是按钮元素
}
</script>
  • apply()/call()求数组最值
var numbers = [5, 458, 120, -215]
var maxInNumbers = Math.max.apply(this.numbers)
console.log(maxInNumbers) //458
var maxInNumbers = Math.max.call(this, 5, 458, 120, -215)
console.log(maxInNumbers) //458
  • 手写bind函数
function fn1(a,b,c) {
console.log('this=', this)
console.log("a b c=",a, b,c)
return 'this is fn1'
}
const fn2 = fn1.bind({x:100}, 10, 20, 30)
const res = fn2()
console.log("res=",res) //返回值
// this= {x: 100}
//a b c= 10 20 30
// res= this is fn1 // 模拟bind
Function.prototype.bind1 = function() {
// 将参数拆解为数组
const args = Array.prototype.slice.call(arguments) //获取this(数组第一项)
const t = args.shift() //fn1.bind(...) 中的fn1
const self = this //返回一个函数
return function () {
return self.apply(t, args)
}
} function fn1(a,b,c) {
console.log('this',this)
console.log(a,b,c)
return 'this.is fn1'
} const fn2 = fn1.bind1({x:100},10,20,30)
const res = fn2()
console.log(res)
03. 如何理解闭包?
  1. 闭包定义和用法:当一个函数的返回值是另一个函数,而返回的那个函数如果调用了其父函数内部的其它变量,如果返回的这个函数在外部被执行,就产生了闭包。
  2. 表现形式:使函数外部能够调用函数内部定义的变量,有两种表现一种是函数作为参数被传递,一种是函数作为返回值被返回闭包,自由变量的查找,是在函数定义的地方,向上级作用域查找,不是在执行的地方。
// 函数作为返回值
function create() {
const a = 100
return function () {
console.log(a)
}
}
const fn = create()
const a = 200
// 函数作为参数被传递
function print(fn) {
const a = 200
fn()
}
const a = 100
function fn() {
console.log(a)
}
pint(fn) //100
  1. 实例如下
  • 作用域链,当前作用域没有声明变量,会向上一级找,找到就返回,没找到就一直找,直到window的变量,这种一层一层的关系就是作用域链。
  • 自由变量,一个变量在当前作用域没有定义,但是被使用了,就会向上级作用域,一层一层依次寻找,直到找到为止。如果全局作用域都没有找到,则报错 xx is not defined。
//这里明显count是函数内部的flag2的那个count。
var count=10; //全局作用域 标记为flag1
function add(){
var count=0; //函数全局作用域 标记为flag2
return function(){
count+=1; //函数的内部作用域
alert(count);
}
}
var s = add()
s();//输出1
s();//输出2
  1. 变量的作用域
  • 作用域代表变量合法的使用范围,要理解闭包,首先必须理解JavaScript特殊的变量作用域。
  • 作用域分,全局作用域、函数作用域、块级作用域(ES6新增)
  • 变量的作用域分类:全局变量和局部变量。
  • 特点:

a. 函数内部可以读取函数外部的全局变量,在函数外部无法读取函数内部的局部变量。

b. 函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量。

  1. 使用闭包的注意点
  • 滥用闭包,会造成内存泄漏。 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
  • 会改变父函数的内部变量的值。 所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
  1. 闭包的应用
  • 隐藏数据不让外边进行改变。非常常用的方式
//做一个缓存的小插件
function createCache() {
const data = {} //闭包中的数据,被隐藏,不被外界访问呢。
return {
set: function (key, val) {
data[key] = val
},
get: function (key) {
return data[key]
}
}
}
const c = createCache()
c.set('a', 100)
console.log(c.get('a')

前端面试准备笔记之JavaScript(02)的更多相关文章

  1. 前端面试准备笔记之JavaScript(03)

    01. 变量声明提升 在预解析的时候,成员变量和函数,被提升到最高的位置,方便其他程序访问. 可以先使用后声明. 只提升变量名,不提升变量值 let const 声明的变量不具有变量声明提升. // ...

  2. 前端面试准备笔记之JavaScript(04)

    01. DOM的本质 xml是一种可扩展的标记性语言,可扩展就是可以描述任何结构的数据,他是一棵树,可以自定义标签,可以自己扩展. html也是一种特定的xml,他规定了一些标签的名称,结构与xml是 ...

  3. 前端面试准备笔记之JavaScript(01)

    1.1 typeof 能判断哪些类型? typeof可以识别所有的值类型 typeof可以识别函数 //function typeof可以判断是否是引用类型(不可以再细分) //object 1.2 ...

  4. 前端面试知识点集锦(JavaScript篇)

    目录 1.谈谈你对Ajax的理解?(概念.特点.作用) 2.说说你对延迟对象deferred的理解? 3.什么是跨域,如何实现跨域访问? 4.为什么要使用模板引擎? 5.JavaScript是一门什么 ...

  5. 问得最多的十个JavaScript前端面试问题

    我知道有很多人不同意这种类型的面试.其实不管你喜不喜欢,你都得接受.尤其当你是自学的,而且要申请第一份工作时.   我估计很多有人其它方法来证明他自己,像Github/ 项目地址可能是非常理想的证明方 ...

  6. web前端面试试题总结---javascript篇

    JavaScript 介绍js的基本数据类型. Undefined.Null.Boolean.Number.String. ECMAScript 2015 新增:Symbol(创建后独一无二且不可变的 ...

  7. 前端面试之JavaScript的基本数据类型!

    前端面试之JavaScript的基本数据类型! JS的基本数据类型 数字 字符串 布尔值 JavaScript中有两个特殊的原始值: null (空) 和undefined (未定义), , 它们不是 ...

  8. 前端面试之JavaScript中数组的方法!【残缺版!!】

    前端面试之JavaScript中数组常用的方法 7 join Array.join()方法将数组中所有元素都转化为字符串并连接在-起,返回最后生成的字 符串.可以指定一个可选的字符串在生成的字符串中来 ...

  9. 前端面试之JavaScript中的闭包!

    前端面试之JavaScript中的闭包! 闭包 闭包( closure )指有权访问另一个函数作用域中变量的函数. ----- JavaScript 高级程序设计 闭包其实可以理解为是一个函数 简单理 ...

随机推荐

  1. 在Linux中要修改一个文件夹或文件的权限

    在Linux中要修改一个文件夹或文件的权限我们需要用到linux chmod命令来做,下面我写了几个简单的实例大家可参考一下. 语法如下: chmod [who] [+ | - | =] [mode] ...

  2. 推荐系统实践 0x12 什么是Embedding

    做过深度学习的小伙伴,大家应该多多少少都听说过Embedding,这么火的Embedding到底是什么呢?这篇文章就用来介绍Embedding.另外,基于深度学习的推荐系统方法或者论文还没有结束,我打 ...

  3. 前置机器学习(五):30分钟掌握常用Matplitlib用法

    Matplotlib 是建立在NumPy基础之上的Python绘图库,是在机器学习中用于数据可视化的工具. 我们在前面的文章讲过NumPy的用法,这里我们就不展开讨论NumPy的相关知识了. Matp ...

  4. C# 9 新特性 —— 增强的 foreach

    C# 9 新特性 -- 增强的 foreach Intro 在 C# 9 中增强了 foreach 的使用,使得一切对象都有 foreach 的可能 我们来看一段代码,这里我们试图遍历一个 int 类 ...

  5. 利用MD5进行加密

    package com.cn.peitest; import java.io.UnsupportedEncodingException; import java.security.MessageDig ...

  6. Map集合,Map常用子类

    Map 集合 1,Collection中的集合,元素是孤立的,向季和忠储存的元素采用一个元素方式储存 2,Map中的集合,元素是成对存在的,每个元素中的集合称为双列集合 3,Collection中的集 ...

  7. SQL数据库创建,创建表,增删改查

    创建数据库:create datebase数据库名 删除数据库:drop datebase 数据库名称 创建表格式: create table 表名(字段名1,字段类型1,字段名2,字段类型2) 查询 ...

  8. hadoop3.2+Centos7+5个节点主从模式配置

    准备工作: hadoop3.2.0+jdk1.8+centos7+zookeeper3.4.5 以上是我搭建集群使用的基础包 一.环境准备 master1 master2 slave1 slave2 ...

  9. Linux 时间同步 05 chrony时间同步

    Linux 时间同步 05 chrony时间同步 目录 Linux 时间同步 05 chrony时间同步 chrony 的优势: chrony包介绍 安装chrony 配置与外部时间服务器进行时间同步 ...

  10. 每日一个linux命令4

    mkdir命令 linux mkdir 命令用来创建指定的名称的目录,要求创建目录的用户在当前目录中具有写权限,并且指定的目录名不能是当前目录中已有的目录. mkdir test    创建一个空目录 ...