-
闭包问题
在JS中,变量的作用域属于函数的作用域,在函数执行完后,变量内存就会被回收。但是,由于闭包函数是建立函数内的子函数,子函数可以访问上级(父级)函数的变量,即使上级函数执行完毕,上级函数中的变量也不会被销毁,这是闭包函数(也就是子函数)便拥有了访问上级作用域中变量的权限。
闭包解决了什么问题
1、可以读取函数内的变量
2、让这些函数内变量的值保存在内存中,不会再函数调用后被清除
闭包的缺点
1、滥用闭包容易造成内存消耗过大,导致网页的性能问题。(可以手动删除不再使用的变量)
2、注意会修改上级函数的属性值
-
for---in 与 for ----of 区别
1、for---of是ES6新引入的特性,循环出来的value,多用于数组;for---in循环出来的是key,多用于对象
-
JS匿名函数 与闭包
参考作者:https://www.jb51.net/article/63986.htm
1、闭包里的this,在运行时指向Window,因为闭包不属于对象的属性或方法
普通函数:由function + name + () + {},四部分组成
匿名函数:就是没有name的函数,如果只是没有name ,浏览器解析时会报错;so
//简单的匿名函数定义方法的其中一种,也叫立即执行匿名函数
(function(){
//do something
})();
//简单的匿名函数定义方法的其中一种,也叫函数里的匿名函数,产生 闭包
function A(){
return function(//参数){
//do something
}
}
//引用
A()(参数)
JS 防抖 与 节流
防抖:在触发事件 n秒后回调函数,若在n秒内再次触发事件,将重新计时。
// 防抖一
var myClickFunc = (function () {
var timeout = null;
return {
debounce:function (fn, wait) {
if(timeout !== null)
clearTimeout(timeout);
timeout = setTimeout(fn, wait);
}
}
})();
// 处理函数
function handle() {
console.log("随机值:",Math.random());
}
// 点击事件
function clickFD(){
myClickFunc.debounce(handle,2000);
}
节流:与防抖不同的是,n秒内不管点击多少次都执行一次且不会重新计时,当执行后才重新计时。
<script>
function throttle(func,delay){
var prev = Date.now();
return function(){
var context = this;
var args = arguments;
var now = Date.now();
console.log("间隔:",now-prev);
if(now - prev >= delay){
func.apply(context,args);
prev = Date.now();
console.log("prev最新值:",prev);
}
};
}
function handle(){
console.log(Math.random());
}
// 触发事件
var func = throttle(handle,1000);
function clickFunc1(){
func();
}
</script>
JS继承方式
- ES6 class 继承
class Animal{
constructor(name){
this.name = name;
}
eat(){
console.log(this.name+",正在吃东西");
}
}
class Cat extends Animal{
catchMouse(){
console.log(`${this.name}`+'抓老鼠');
}
}
var cat = new Cat('Tom猫');
cat.catchMouse();
- 原型继承
function Animal(name){
this.name = name;
}
Animal.prototype.eat = function(){
console.log(this.name+'正在吃东西');
}
function Cat(furColor){
this.furColor =furColor
}
Cat.prototype = new Animal('tom');
var tom = new Cat('red');
console.log(tom);//cat 实例 ,animal实例
console.log(tom.__proto__.eat());//通过__proto__向上获取
- 构造继承
- 寄生组合式继承
- 实例继承
this 含义
//简单的函数调用
var x = 1;
function test(){
console.log(this.x);
}
test();//1
//函数作为对象方法的调用,this 指上级对象
function test(){
console.log(this.x);
}
var obj = {};
obj.x = 1;
obj.m = test();
obj.m();//1
//作为构造函数调用,生成了一个新对象,这是this就这项new 新对象
function test(){
this.x = 1;
}
var obj = new test();
obj.x //1
//apply,call ,bind 调用,this指的是第一个参数对象
变量的提升
函数声明和变量声明总是会被解释器悄悄地“提升”到方法体的最顶部。初始化不会提升
var x = 5; // 初始化 x
var y; // 声明 y
ProtoType
已存在的对象构造器中无法直接添加属性和方法,这里需要借助prototype属性。
判断对象类型
var a = 3;
var b = "test string";
var c = new Date();
var d = [1,2,3,4];
var e = false;
var f = Math.random();
//typeof 只区分原始类型 与 对象
console.log("对象类型:",typeof(a));//number
console.log("对象类型:",typeof(b));//string
console.log("对象类型:",typeof(c));//object
console.log("对象类型:",typeof(d));//object
console.log("对象类型:",typeof(e));//boolean
//instanceof 适用于区分对象Array 、Date 、Object、RegExp
console.log(a instanceof Array);//false
//精确的判断是否为数组的方法:跨原型链调用toString()
//当Object.prototype.toString(o)执行后
// 1)获取对象o的class属性。 2)连接字符串:"[object 1]" )返回结果(1)
Object.prototype.toString.call(d);//返回[object Array]
同步与异步
- Javascript是单线程的
- 计算机的同步与异步,与现实中生活中理解的同步与异步是相反的。计算机中,同步指的的排一个队做事,异步是多个队做事