一、閉包:
1、概念
通過作用域的嵌套,將原本的局部變量渡讼,進(jìn)化成私有變量(自由變量)的環(huán)境
通俗理解的閉包: 一個內(nèi)部函數(shù)引用了外部函數(shù)的變量,外部函數(shù)形成了一個閉包.
function fun1(){
var n=999;
function fn2(){
console.log(n);
}
return fn2; //fn2 就是一個閉包函數(shù),因?yàn)樗軌蛟L問到fun1函數(shù)的作用域
}
var r=fun1();
r();
2耳璧、原理
函數(shù)在執(zhí)行時成箫,可以拿到自身的定義作用域內(nèi)的變量
觸發(fā)了垃圾回收機(jī)制
將暫時不用的數(shù)據(jù),暫存起來旨枯,如果需要使用蹬昌,可以再次調(diào)出,除非真正不用了攀隔,再進(jìn)行刪除
3皂贩、特點(diǎn)
設(shè)置私有變量(內(nèi)部函數(shù)調(diào)用外部函數(shù)的局部變量,這個局部變量就會變成內(nèi)部函數(shù)的私有變
量)閉包的作用:充當(dāng)一個攝像頭,函數(shù)外部可以訪問函數(shù)內(nèi)部的變量,減少變量的聲明,避免造成污染.
使用不當(dāng)會很容易造成內(nèi)存泄露(內(nèi)存中能存的東西越來越少,像是其他部分被泄露了一樣)
內(nèi)存的占用比較大,浪費(fèi)內(nèi)存.
4昆汹、應(yīng)用場景
// - 事件委托的封裝
function eveEnt(child, cb){
return function(eve){
var e = eve || window.event;
var tar = e.target || e.srcElement;
for(var i=0;i<child.length;i++){
if(tar === child[i]){
cb.call(tar);
}
}
}
}
// - 循環(huán)綁定事件明刷,事件中使用循環(huán)的計(jì)數(shù)器
for(var i=0;i<ali.length;i++){
(function(index){
ali[index].onclick = function(){
console.log(index);
}
})(i)
}
for(var i=0;i<ali.length;i++){
ali[i].onclick = (function(index){
return function(){
console.log(index);
}
})(i)
}
//- 內(nèi)置函數(shù)的回調(diào)函數(shù)傳參
setTimeout(fn("hello"),1000);
function fn(a){
return function(){
console.log(a);
}
}
二、繼承
1满粗、 改變 this 指向的繼承
function Parent(){
this.skill = "敲代碼";
this.abc = 123;
this.show = function(){
console.log(this.skill)
}
}
Parent.prototype.init = function(){
console.log("hello")
}
function Tea1(){
this.s1 = "語文";
}
function Tea2(){
this.s2 = "數(shù)學(xué)";
}
function Tea3(){
this.s3 = "英語";
}
function Child(){
// Parent(); // this指向window
// 改變成將來Child的實(shí)例
// 在Child的函數(shù)中的this辈末,就是將來Child的實(shí)例
// 將Parent的this改成Child的this
Parent.call(this);
Tea1.apply(this);
Tea2.bind(this)();
Tea3.call(this);
}
// var p = new Parent();
// console.log(p);
// console.log(p.skill);
var c = new Child();
console.log(c)
console.log(c.skill)
c.show();
c.init();
改變this指向繼承:
對象之間的繼承
類與類之間
特點(diǎn)
簡單方便易操作,可以實(shí)現(xiàn)多繼承
只能繼承構(gòu)造函數(shù)中的內(nèi)容,不能繼承原型上的內(nèi)容
2挤聘、 原型繼承
function Parent(){
this.skill = "敲代碼";
}
Parent.prototype.init = function(){
console.log("hello");
}
function Child(){
}
// Child.prototype = Parent.prototype;
for(var i in Parent.prototype){
Child.prototype[i] = Parent.prototype[i];
}
// Child.prototype.init = function(){
// console.log("world")
// }
var p = new Parent();
p.init()
console.log(p)
var c = new Child();
c.init();
console.log(c)
// - 可以繼承原型上所有內(nèi)容轰枝,但是不能繼承構(gòu)造函數(shù)
3、原型鏈繼承
function Parent(s){
this.skill = s;
}
Parent.prototype.init = function(){
console.log(this.skill);
}
function Child(){
}
Child.prototype = new Parent("hello");
// Child.prototype.init = function(){
// console.log("world")
// }
var p = new Parent("敲代碼");
p.init()
console.log(p)
var c1 = new Child();
c1.init();
console.log(c1)
var c2 = new Child();
c2.init();
console.log(c2);
// 原型繼承-原型鏈繼承:
// 可以繼承原型组去,可以繼承構(gòu)造函數(shù)
// 不利于傳參
4狸膏、混合繼承
function Parent(s){
this.skill = s;
}
Parent.prototype.init = function(){
console.log(this.skill);
}
function Tea1(){
this.s1 = "語文"
}
Tea1.prototype.show = function(){
console.log(this.s1);
}
function Child(s){
Parent.call(this, s);
Tea1.call(this);
}
for(var i in Parent.prototype){
Child.prototype[i] = Parent.prototype[i];
}
for(var i in Tea1.prototype){
Child.prototype[i] = Tea1.prototype[i];
}
// Child.prototype.init = function(){
// console.log("world")
// }
var p = new Parent("敲代碼");
p.init()
console.log(p)
// p.show()
var c1 = new Child("敲鍵盤");
c1.init();
console.log(c1)
c1.show();
// 混合繼承特點(diǎn):
// 可以繼承構(gòu)造函數(shù),可以繼承原型添怔,還可以實(shí)現(xiàn)多繼承
5、class 繼承
class Parent{
constructor(s){
this.skill = s;
}
init(){
console.log(this.skill)
}
}
class Child extends Parent{
constructor(s){
super(s);
}
init(){
console.log("hello")
}
}
var p = new Parent("敲代碼");
p.init();
console.log(p);
var c = new Child("敲鍵盤");
c.init();
console.log(c);
- ES6對混合繼承的封裝
6贤旷、Object.create() Array.from() 方法
var obj = {
name:"admin"
}
var obj2 = Object.create(obj);
// console.log(obj2 === obj); // f
var arr1 = [1,2,3]
var arr2 = Array.from(arr1);
console.log(arr1 === arr2); //f
// 偽數(shù)組:有索引广料,有長度,但是不能使用數(shù)組的方法
// arguments
// 選擇器選擇到的數(shù)組
var aspan = document.querySelectorAll("span");
// 偽轉(zhuǎn)真
// 1.逐個遍歷幼驶,拷貝到新數(shù)組
// var arr = [];
// for(var i=0;i<aspan.length;i++){
// arr.push(aspan[i])
// }
// arr.push("hello")
// console.log(arr)
// 2.利用Array的方法from
var arr = Array.from(aspan);
arr.push("world");
console.log(arr);