整理一下最近前端的充電筆記,慚愧之前一直沒有去很好的理解原型和閉包前端
函數也是對象es6
instanceof Object===trueajax
函數有屬性: prototypejson
函數有方法: call()/apply()數組
能夠添加新的屬性/方法promise
函數的3種不一樣角色瀏覽器
通常函數 : 直接調用安全
構造函數 : 經過new調用服務器
對象 : 經過.調用內部的屬性/方法閉包
函數中的this
顯式指定誰: obj.xxx()
經過call/apply指定誰調用: xxx.call(obj)
不指定誰調用: xxx() : window
回調函數: 看背後是經過誰來調用的: window/其它
匿名函數自調用:
(function(w, obj){ //實現代碼 })(window, obj)
專業術語爲: IIFE (Immediately Invoked Function Expression) 當即調用函數表達式
回調函數的理解
什麼函數纔是回調函數?
你定義的
你沒有調用
但它最終執行了(在必定條件下或某個時刻)
經常使用的回調函數
dom事件回調函數
定時器回調函數
ajax請求回調函數
生命週期回調函數
全部函數都有一個特別的屬性:
prototype
: 顯式原型屬性
全部實例對象都有一個特別的屬性:
__proto__
: 隱式原型屬性
顯式原型與隱式原型的關係
函數的prototype: 定義函數時被自動賦值, 值默認爲{}, 即用爲原型對象
實例對象的__proto__: 在建立實例對象時被自動添加, 並賦值爲構造函數的prototype值
原型對象即爲當前實例對象的父對象
原型鏈
全部的實例對象都有__proto__屬性, 它指向的就是原型對象
這樣經過__proto__屬性就造成了一個鏈的結構---->原型鏈
當查找對象內部的屬性/方法時, js引擎自動沿着這個原型鏈查找
當給對象屬性賦值時不會使用原型鏈, 而只是在當前對象中進行操做
理解:
當嵌套的內部函數引用了外部函數的變量時就產生了閉包
閉包本質是內部函數中的一個對象, 這個對象中包含引用的變量屬性
做用:
延長局部變量的生命週期
讓函數外部能操做內部的局部變量
隨便寫一個閉包程序
function fn1() { var a = 2; function fn2() { a++; console.log(a); } return fn2; } var f = fn1(); f(); f();
閉包應用:
模塊化: 封裝一些數據以及操做數據的函數, 向外暴露一些行爲
循環遍歷加監聽
JS框架(如:jQuery)大量使用了閉包
缺點:
變量佔用內存的時間可能會過長
可能致使內存泄露
解決:
及時釋放 : f = null; //讓內部函數對象成爲垃圾對象
js是單線程執行的(回調函數也是在主線程)
只能是主線程更新界面
定時器並不真正徹底定時
若是在主線程執行了一個長時間的操做, 可能致使延時才處理
對象的擴展通常經過原型
字符串
對象
簡化的對象寫法
let name = 'Tom'; let age = 12; let person = { name, age, setName (name) { this.name = name; } };
Object.assign(target, source1, source2..) : 將源對象的屬性複製到目標對象上
Object.is(v1, v2) : 判斷2個數據是否徹底相等
__proto__屬性 : 隱式原型屬性
數組
函數
解決回調地獄
(回調函數的層層嵌套, 編碼是不斷向右擴展, 閱讀性不好)
能以同步編碼的方式實現異步調用
在es6以前原生的js中是沒這種實現的, 一些第三方框架(jQuery)實現了promise
ES6中定義實現API:
// 1. 建立promise對象 var promise = new Promise(function(resolve, reject){ // 作異步的操做 if(成功) { // 調用成功的回調 resolve(result); } else { // 調用失敗的回調 reject(errorMsg); } }) // 2. 調用promise對象的then() promise.then(function( result => console.log(result), errorMsg => alert(errorMsg) ))
CommonJS
Node.js : 服務器端
Browserify : 瀏覽器端 也稱爲js的打包工具
基本語法:
定義暴露模塊 : exports
exports.xxx = value module.exports = value
引入模塊 : require
var module = require('模塊名/模塊相對路徑')
引入模塊發生在何時?
ES6內置了模塊化的實現
基本語法
定義暴露模塊 : export
暴露一個對象:
export default 對象
暴露多個:
export var xxx = value1 export let yyy = value2 var xxx = value1 let yyy = value2 export {xxx, yyy}
引入使用模塊 : import
default模塊:
import xxx from '模塊路徑/模塊名'
其它模塊
import {xxx, yyy} from '模塊路徑/模塊名' import * as module1 from '模塊路徑/模塊名'
問題: 全部瀏覽器還不能直接識別ES6模塊化的語法
解決: