【前端】JavaScript这样服用,效果更佳

1. var和let

  • JS中作用域有:全局作用域、函数作用域。没有块作用域的概念。ECMAScript 6(简称ES6)中新增了块级作用域
  • 块作用域由 { } 包括, if 语句和 for 语句里面的 { } 也属于块作用域

1.1 ES5问题

1.1.1 全局变量

  • 在if或者for循环中声明的变量会变成全局变量
for(var i=0;i<=5;i++){
console.log("hello");
}
console.log(i); //5 

1.1.2 内层变量可能会覆盖外层变量

var a = 1;
function fn() { console.log(a); if (false) {var a = 2;}
 }
fn(); //undefined 

1.2 let

  • 允许块级作用域任意嵌套
  • 外层作用域无法读取内层作用域的变量
  • 内层作用域可以定义外层作用域的同名变量
  • 函数本身的作用域在其所在的块级作用域之内
'use strict'
function fn() {console.log("out");
}
(function () {if (false) {function fn() {console.log("in"); }
} fn();
}()); 

1.3 var&let&const

  • var定义的变量没有块的概念,可以跨块访问,不能跨函数访问,有变量提升,可重复声明
  • let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问,无变量提升,不可以重复声明
  • let 声明的变量只在块级作用域内有效,不存在变量提升,而是绑定在暂时性死区
  • 或者说let变量提升了,但是在let声明变量前不能使用该变量,这特性叫暂时性死区(temporaldead zone)
  • 如果有重复变量 let 会在编译阶段报错

1.3.1 暂时性死区

// 不存在变量提升
'use strict';
function func(){console.log(i);let i;
 };
func(); // 报错 

1.3.2 全局变量

  • ES5声明变量只有两种方式:var和function
  • ES6有let、const、import、class再加上ES5的var、function共有六种声明变量的方式
  • 浏览器环境中顶层对象是window,Node中是global对象
  • ES5中 顶层对象的属性等价于全局变量
  • ES6中var、function声明的全局变量,依然是顶层对象的属性;let、const、class声明的全局变量不属于顶层对象的属性

2. this

  • 当前函数的this是在被调用的时候才能确定的
  • 如果当前的执行上下文处于调用栈的栈顶,这个时候变量对象变成了活动对象,THIS指针才能确定

2.1 全局对象

  • 全局对象this指向本身
var a=1;//声明绑定变量对象,但在全局环境中,变量对象就是全局对象
this.b=2;//this绑定全局对象
c=3;//赋值操作 隐式绑定 

2.1 用点调用

  • 在一个函数上下文中,this由函数的调用者提供,由调用函数的方式来决定指向
  • 如果是函数执行,如果前面有点,那么点前面是谁 this 就是谁
let obj = {getName(){console.log(this);}
};
obj.getName(); 

2.2 直接调用

  • 如果没有,this就是window(严格模式下是undefined),自执行函数中的this一般都是window
let obj = {getName(){ console.log(this); }
};
let getName = obj.getName;
getName(); 

2.3 绑定事件

  • 给元素绑定事件的时候,绑定的方法中的this一般是元素本身
container.addEventListener('click',function(){console.log(this);
}); 

2.4 箭头函数

  • 箭头函数没有自己的this
  • 也没有prototype
  • 也没有arguments
  • 无法创建箭头函数的实例
let fn = () => {console.log(this);console.log(arguments);//Uncaught ReferenceError: arguments is not defined
 }
console.log(fn.prototype);//undefined
fn();
new fn();//VM4416:8 Uncaught TypeError: fn is not a constructor 

2.5 构造函数

  • 构造函数中的THIS是当前类的实例
function fn(){}
let obj = new fn(); 

2.6 call/apply/bind

  • call/apply/bind可以改变函数中this的指向
  • 第一个参数是改变this指向(非严格模式下,传递null/undefined指向也是window)
  • call参数是依次传递,apply是以数组的方式传递
!function (proto) { function getContext(context) {context = context || window;var type = typeof context;if (['number', 'string', 'boolean', 'null'].includes(type)) {context = new context.constructor(context); } return context;} function call(context, ...args) { context = getContext(context); context._fn = this; let result = context._fn(...args); delete context._fn; return result; } function apply(context, args) {context = getContext(context);context._fn = this;let result = context._fn(...args);delete context._fn; return result;
 } function bind(context, ...bindArgs) {return (...args) => this.call(context, ...bindArgs, ...args);
} proto.call = call; proto.apply = apply; proto.bind = bind;
}(Function.prototype) 

2.7绑定

  • 默认绑定
  • 隐式绑定
  • 显式绑定
  • new绑定
  • new > 显式 > 隐式 > 默认

隐式 > 默认

function one() {console.log(this)
}
var obj = { name: "obj", one
}
obj.one() 

显式 > 隐式

function one() {console.log(this)
}
var obj = {name: "obj",one: one.bind("hello")
}
obj.one() 

new > 显式

function one() {console.log(this)
}
var helloOne = one.bind("hello")
var obj = new helloOne();
console.log(obj); 

最后

整理了一套《前端大厂面试宝典》,包含了HTML、CSS、JavaScript、HTTP、TCP协议、浏览器、VUE、React、数据结构和算法,一共201道面试题,并对每个问题作出了回答和解析。

有需要的小伙伴,可以点击文末卡片领取这份文档,无偿分享

部分文档展示:



文章篇幅有限,后面的内容就不一一展示了

有需要的小伙伴,可以点下方卡片免费领取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值