雪碧圖 http緩存 虛擬dom webpackjavascript
爲何要三次握手? 三次握手: A:我能連你了嗎? B: 能夠連我,你連吧 A:那我連你了 開始發送數據css
緣由:由於要保證A/B 均可以收發信息 ,數據才能在AB之間傳輸html
A:我能連你了嗎? B: 能夠 說明A能夠發信息,B能夠接受信息html5
B: 能夠連我,你連吧 A:那我連你了 說明B能夠發送信息,A能夠接受信息java
html5中新增長的標籤,技術(api)(包括promise,localStorage,canvas等),統稱爲html5.webpack
.
類選擇器,#
id選擇器,input[type=text] [data-x] [target=_blank]
屬性選擇器web
直接子代選擇器>
後代選擇器空格 ,
表明兩個都選面試
僞類選擇器:
input:focus
選擇得到焦點的 input 元素。 a:hover
p:first-child
p:last-child
p:nth-child(1)
p:nth-child(even)
p:nth-child(odd)
p:before
p:after
ajax
input:enabled
選擇每一個啓用的 元素。 input:disabled
選擇每一個禁用的 元素 input:checked
選擇每一個被選中的 元素。canvas
div{
border:1px solid red;
/*如下三行*/
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
}
複製代碼
float
position:absolute
position:fixed
注意: position:relative
沒有脫離文檔流,只是相對於以前的位置定位,原來的地方還佔據位置。position:absolute;top:0;bottom:0;left:0;right:0;margin:auto;
SVG:SVG實際上是一段代碼,瀏覽器能夠解析這段代碼,將它變成圖形 優勢:能夠漸變,不會失真,能夠動
我理解flex從兩個方面去理解:
/*容器上:*/
flex-direction/* 彈性元素按主軸排列的方向*/
flex-wrap/*nowrap | wrap | wrap-reverse,主軸排列不下,是否換行 。默認是nowrap不折行。不會溢出。元素的彈性伸縮*/
flex-flow/*上面兩個的縮寫*/
justify-content/* 主軸對齊方式,五個屬性*/
align-items/* 單行交叉軸的元素對齊方式。默認stretch(元素未在交叉軸上設置尺寸,將把交叉軸自動填滿,有flex-start,end,center,baseline幾個屬性)*/
align-content/*多行交叉軸的對齊方式。flex-wrap: wrap的時候。stretch(這幾行在垂直方向上佔滿) | flex-start(這幾行擠在上面) | flex-end(擠在下面) | center(擠在中間) | space-between | space-around */
/*元素上:*/
order/* 元素排列次序*/
align-self/* 單個元素的align-items*/
複製代碼
flex-wrap: nowrap;
時,元素會伸縮。 在元素上寫:flex-shrink
默認爲1,按比例縮小,佔滿一行flex-grow:
放大比例。默認爲0,不放大。若是兩個子元素flex-grow:3,flex-grow:2,那麼意思就是剩下的空間按3:2分配。flex-basis
默認爲爲auto
。若是有width
,就由width
決定,若是沒有width
,就由內容的寬度決定。
flex-basis
有數值。忽略width
,由flex-basis
決定flex-basis:0
由內容寬度決定。由於他的優先級比width
高flex
是上面三個的縮寫。
flex: 1 = flex: 1 1 0%
既之內容的大小(無論width是多少) 按比例放大或縮小,佔滿一行 -flex: auto = flex: 1 1 auto;
既考慮width, 按比例放大或縮小,佔滿一行flex: none = flex: 0 0 auto;
不放大也不縮小,width是多少,就是多少經常使用於固定尺寸 不伸縮width: calc(50% - 10px);
寬度100%會把父盒子撐破, 解決方法:
box-sizing:border-box;
width: calc(100% - 10px);
聖盃佈局和雙飛翼佈局 是老的佈局方式,2012年之前流行,如今已不流行,可是面試可能會考察到. why it?
原理:實際上都用了浮動和負邊距的特性。 雙飛翼實現方法: 1先所有fl 2main width100% 3 左邊的一塊 margin-left: -100%; /4/ 右邊的一塊 margin-left: -150px; /5/ 4.main.wrap{ margin-left: 100px; /6/ margin-right: 150px; /6/ background: blue; /7/ height: 350px; /7/ } 雙飛翼:js.jirengu.com/fevifumike/…
內部元素徹底包起來(float等),外部元素界限分明,不重疊。
面試官問的時候就說:
@media (max-width: 768px){/*0-768*/
body{
background-color: blue;
}
}
@media (max-width: 425px){/*0-425*/
body{
background-color: red;
}
}
複製代碼
2.加上meta viewport
歷史緣由:最開始手機瀏覽器(蘋果三)會在本身的三四百像素的手機上模擬980像素的顯示效果,而後讓用戶本身去縮放,查看網頁. 那麼就告訴瀏覽器不要縮放網頁,手機屏幕是多少像素,就顯示多少像素的網頁.使用下面的代碼<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
複製代碼
手機端什麼CSS屬性均可以用,不用考慮兼容的問題
動態 REM是手機專用,是如何適配全部手機的方案。 em
:一個m的寬度.若是面試官問,就說是一個漢字的寬度.這個單位是相對於font-size的 rem
:root em,根元素的font-size
.即 <html>
的font-size
.rem是相對於html的font-size的.
vh
:視口高度,總共100vh
vw
:視口寬度,總共100cw
pc端只須要選一個佈局(flex或者float),而後定寬就能夠了。可是手機端不行,由於屏幕太多了 解決方法:
動態rem: 由於rem
這個單位跟<html>
標籤的font-size
掛鉤。那麼用js
將<html>
標籤的font-size
與頁面寬度掛鉤(pagewidth),那麼rem
這個單位就間接地與頁面寬度掛鉤了。
<head>
<meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <title>動態REM</title> <script></script> </head> 複製代碼
而後佈局等大單位就用rem,可是border,font-size等小單位,還用px便可,由於這些單位就算統一,在任何手機上的表現都沒有多少影響。
這樣寫以後,10rem就是頁面寬度。這樣就能夠總體按比例縮放了。
&&
,他的返回值就是遇到的第一個falsy值,後面的不看了 1&&2&&3&&0&&2&&3
返回0,後面的不運行。 ||
,他返回的就是第一個遇到的true值,後面的不看 0||0||0||false||1||2||0
返回1,後面的不運行。
七種數據類型分爲六個基本類型和對象。 六個基本類型分別是null
,undefined
,string
,number
,boolean
,symbol
對象又分爲object
,function
,array
相同點:if裏都是都是false值
不一樣點:
null
轉換爲數字的時候是0
, undefined
表示未定義轉換爲數字的時候是NaN
調用函數時,某個參數未設置任何值,這時就能夠傳入null
,表示該參數爲空。而傳入undefined
就表明undefined
yuchengkai.cn/docs/zh/fro… typeof只須要記住兩點。
null
顯示爲 object
,其他均可以顯示正確的類型function
都會顯示object
Array.isArray(arr)
方法能夠識別數組。除了下面六個值被轉爲false
,其餘值都視爲true
undefined
null
false
0
NaN
""或''(空字符串)
複製代碼
NaN === NaN; // false
typeof NaN//number
複製代碼
for in 遍歷對象
for in循環注意點
for(var key in person){
console.log(person.key)
}
複製代碼
注意:person.key
等於 person['key']
要用 這裏遍歷要用person[key]
for... in可能會隨機遍歷,不按照聲明順序
forEach遍歷數組
var arr=[1,2,3]
arr.forEach(function(e){
console.log(e)
})
//1 2 3
複製代碼
null
和undefined
沒有tostring()
方法。只能null+''
和undefined+''
.toString()
方法。或直接+''
。或者window.String()
方法五個方法
'1234'-0
(經常使用)parseInt()
//默認十進制+'1'
取正記住5個false值 null undefined NaN 0 ''
記住下面易錯點:
[]//ture
{}//ture
' '//ture 裏面有空格
複製代碼
轉換方法兩個:
window.Boolean(xxx)
!!xxx
引用: 一個廣義對象(object,array,function) 例如 var a= {xxx:'xxx'} a存的是{xxx:'xxx'}這個廣義對象的地址,假如是10000。那麼a(或a存的地址10000)就是這個對象({xxx:'xxx'})的引用。
var a = 1 var b = a b = 2 請問 a 顯示是幾? 2 1 (深拷貝)
var a = {name: 'a'}
var b = a
b = {name: 'b'}
複製代碼
請問如今 a.name 是多少? 'a'
var a = {name: 'a'}
var b = a
b.name = 'b'
複製代碼
請問如今 a.name 是多少? 'b'
var a = {name: 'a'}
var b = a
b = null
複製代碼
請問如今 a 是什麼? {name: 'a'}
若是一個對象沒有被引用,他就是垃圾,就會被回收(沒有引用找不到他,因此要回收)
{name:'a'}
就是垃圾,就要被
回收,
釋放內存
不會回收,由於
document.body.onclick
這個
引用在棧內存中存了fu這個函數的
地址
內存泄漏:在ie6的時候,若是關閉頁面,一些垃圾是沒有被清除,內存被永久的佔用了
因此:
如何實現對象的淺與深拷貝?
Object.assign
來解決這個問題。let a = {
age: 1
}
let b = Object.assign({}, a)
a.age = 2
console.log(b.age) // 1
複製代碼
Object.assign()只拷貝第一層,若是屬性存的是一個引用,那麼他也只拷貝到引用。因此是淺拷貝JSON.parse(JSON.stringify(object))
來解決。let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = JSON.parse(JSON.stringify(a))
a.jobs.first = 'native'
console.log(b.jobs.first) // FE
複製代碼
可是該方法也是有侷限性的:
undefined
JavaScript有函數級做用域,僅僅函數能建立新做用域。
變量的做用域表示這個變量存在的上下文。
setTimeout中的函數所處在於全局做用域中,因此函數中使用this
關鍵字時,這個this
關鍵字指向的是全局對象(window
)
兩個題目
var foo = 1;
function bar() {
if (!foo) {
var foo = 10;
}
alert(foo);
}
bar();
複製代碼
答案是10
第二個例子
var a = 1;
function b() {
a = 10;
return;
function a() {}
}
b();
alert(a);
複製代碼
alert輸出了1
變量提高後的順序 提高時代碼表現上的排序爲:
1 var a;
2 function f (){}
3 形參
4 this和arguments
複製代碼
總結: var
聲明變量,只會提高var a=undefined
(自動賦值爲undefined
)。 function
聲明函數,function f (){}
,全部的都會提高。
{ console.log(x) // Uncaught ReferenceError: x is not defined let x = 1 } let x = 1以前到花括號{,就是x的暫時死區,不用使用變量x,const同樣
instanceof
運算符用來驗證,一個對象是否爲指定的構造函數的實例。obj instanceof Object
返回true
,就表示obj
對象是Object
的實例。
api太多
使用new命令時,它後面的函數依次執行下面的步驟。
既:
新對象.__proto__=構造函數.prototype
)this = 新對象
)第一步寫私有屬性,第二步寫共有屬性.
能夠看到這個對象的
1自有屬性 2__proto__指向的原型對象含有共有屬性. 3 共共有屬性(原型的屬性)constructor指向的構造函數以現有的對象做爲模板,生成新的實例對象,這時就可使用Object.create()
方法。
var person1 = {
name: '張三',
age: 38,
greeting: function() {
console.log('Hi! I\'m ' + this.name + '.');
}
};
var person2 = Object.create(person1);
person2.name // 張三
person2.greeting() // Hi! I'm 張三.
複製代碼
this的實質:
this
就出現了,它的設計目的就是在函數體內部,指代函數當前的運行環境。總結一句話:this就是指函數所在的當前環境(既所在的對象)
this:
this
表明新生成的實例對象this
就是屬性或方法「當前」所在的對象。它老是返回一個對象。面試回答:;
fn()
裏面的 this
就是 window
(fn在最頂層)fn()
是 strict mode
,this
就是 undefined
(fn在最頂層,嚴格模式下是undefined)a.b.c.fn()
裏面的 this
就是 a.b.c
(屬性或方法當前所在的對象。)new F()
裏面的 this
就是新生成的實例() => console.log(this)
裏面 this
跟外面的 this
的值如出一轍(ES6新增語法)(箭頭函數裏,this
就上一層的this
的值) 面試答上面的幾個↑面試回答call() apply() bind(): 1 call()方法,能夠指定函數內部this
的指向(即函數執行時所在的做用域),而後在所指定的做用域中,調用該函數。 (這個所指定的做用域意思就是所指定的對象)
var obj = {};
var f = function () {
return this;
};
f() === window // true
f.call(obj) === obj // true
複製代碼
call
後面的參數則是函數調用時所需的參數
2 apply()
與call()
惟一的區別就是,它接收一個數組做爲函數執行時的參數。
x.call(obj,1,2,3)
x.apply(obj,[1,2,3])
複製代碼
3 bind方法用於將函數體內的this綁定到某個對象,而後返回一個新函數。 call
和apply
都是綁定新this
後直接執行函數,而bind
沒有執行,而是返回新函數,這個在一函數做爲參數的一些方法裏就用bind
this面試題 帶call的面試題遵循如下兩個規則
若是call傳了參數,this就是傳的參數。
若是call沒傳參數或者爲undefined,那麼this是window(飛嚴格模式),或者undefined(嚴格模式)
帶call的面試題仍然遵循規則 3.
4.記住了,當call()
的第一個參數是undefined
的時候, this
是 window
.
this面試題 this題目
答案: 調用B處的console.log().結果是options window(console.log()中console是全局window對象裏的一個方法)
第二題:
答案:D Object
第三題:
答案:Object
舉例
var a = [1,2,3]
a.push(4)
,push
是哪來的?a.__proto__ === Array.prototype
(a是實例數組對象,Array是構造函數)push
函數 就是沿着 a.__proto__
找到的,也就是 Array.prototype.push
Array.prototype
還有不少方法,如join
、pop
、slice
、splice
、concat
Array.prototype
就是 a 的原型(proto)聚完例子後用new對象舉例,說給面試官聽: 比若說
咱們新建立一個構造函數
function Person() {}
複製代碼
而後根據構造函數構造一個新對象
var person1 = new Person();
``` 複製代碼
每一個函數都有一個 prototype
屬性,這個構造函數的 prototype 屬性指向了一個對象,這個對象正是調用該構造函數而建立的實例的原型。
當咱們給Person
的prototype
的name
屬性賦值爲'Kevin'
Person.prototype.name = 'Kevin';
var person1 = new Person();
var person2 = new Person();
console.log(person1.name) // Kevin
console.log(person2.name) // Kevin
複製代碼
每個新的實例對象對象都會從原型"繼承"屬性,實例對象擁有該原型的全部屬性。
說白了,原型就是 構造函數 用來 構造 新實例 的 模板對象。
這就是原型。 開始解釋原型鏈 那麼咱們該怎麼表示實例與實例原型,也就是 person1 和 Person.prototype 之間的關係呢,這時候咱們就要講到第二個屬性__proto__
。
先回答什麼是原型。在上面,而後繼續從__proto__
開始往下說。
說:
JavaScript對象除了 null 都具備的一個屬性,叫__proto__
,這個屬性會指向該對象的原型對象。
當讀取實例的屬性時,若是找不到,就會經過__proto__
查找原型中的屬性,若是還查不到,就去找原型的原型。
例如Person.prototype
這個原型的原型就是Object
這個構造函數的prototype
,既Object.prototype
這個原型對象。而後,Person.prototype.__proto__
就指向Object.prototype
這個原型。而後Object.prototype
原型是null
。
這些原型對象經過__proto__
像鏈子同樣連起來,就叫作原型鏈。 而後給面試官畫:
鏈子上都畫上__proto__
person1----->Person.prototype----->Object.prototype----->null
Array.prototype----->Object.prototype----->null
實例的.__proto__
指向構造函數. prototype
(原型對象) 面試題:
Number.prototype.__proto__ === Object.prototype
//true
String.prototype.__proto__ === Object.prototype
//true
Boolean.prototype.__proto__ === Object.prototype
//true
Array.prototype.__proto__ === Object.prototype
複製代碼
//同理
Function.prototype.__proto__=== Object.prototype//true
複製代碼
關於 Function只需記住下面: 構造函數的原型:
String.__proto__===Function.prototype//true
Number.__proto__===Function.prototype//true
Boolean.__proto__===Function.prototype//true
Object.__proto__ === Function.prototype//true
複製代碼
特殊的:
Function.__proto__===Function.Prototype//true
複製代碼
每個構造函數的prototype屬性都指向原型對象。 每個原型對象的constructor屬性都指向構造函數。 原型對象
console.log(Person === Person.prototype.constructor); // true
複製代碼
大BUG:var a = Array(3)
一個參數,且參數爲數字,那麼久聲明數組長度爲3的空數組
var a = Array(3,3)
兩個參數以上的時候,裏面的參數都是數組內部的值。 因此聲明數組不要用new Array()的方法。
數組本質上是一個對象。
數組能夠用for i和for in循環
僞數組:
__proto__
指向Object.prototype
,沒有pop
push
等方法length
arguments
,表明函數裏面所傳入的全部的參數。forEach
[1,2,3].forEach(function(value,index){
console.log(value)
console.log(index)
})
複製代碼
sort&join&concat&map&filter&reduce segmentfault.com/a/119000001…
什麼是DOM?
什麼是DOM樹?
Javascript操做DOM經常使用API總結http://luopq.com/2015/11/30/javascript-dom/
6Document.querySelectorAll()
函數聲明的五種方式
注意其中一種方式:
1具名函數
function f(x,y){
return x+y
}
f.name // 'f'
2匿名函數
var f
f = function(x,y){
return x+y
}
f.name // 'f'
3具名函數賦值
var f
f = function f2(x,y){ return x+y }
f.name // 'f2'
console.log(f2) // undefined
4window.Function
var f = new Function('x','y','return x+y')
f.name // "anonymous"
5箭頭函數
var f = (x,y) => {
return x+y
}
f.name//"f"
複製代碼
只要記住三、4兩種特殊的狀況就好。
做用:建立一個獨立的做用域,避免變量污染
(function(){alert('我是匿名函數')} ()) // 用括號把整個表達式包起來
(function(){alert('我是匿名函數')}) () //用括號把函數包起來
//下面的都是執行這個表達式,而無論返回值是什麼
!function(){alert('我是匿名函數')}()
複製代碼
另外一種建立獨立做用域的方法是使用let
題目:
var a = 1
function f1(){
var a = 2
console.log(a)
f4()
}
function f4(){
console.log(a)
}
f1()
複製代碼
答案,2,1 這個f4裏面的a只能是他本身自己的做用域和他的父做用域,跟f1裏面的a沒有關係 先看面試題 題目1
var a = 1
function fn1(){
function fn2(){
console.log(a)
}
function fn3(){
var a = 4
fn2()
}
var a = 2
return fn3
}
var fn = fn1()
fn() //2
複製代碼
題目2
var a = 1
function fn1(){
function fn3(){
var a = 4
fn2()
}
var a = 2
return fn3
}
function fn2(){
console.log(a)
}
var fn = fn1()
fn() //1
複製代碼
題目3
var a = 1
function fn1(){
function fn3(){
function fn2(){
console.log(a)
}
var a
fn2()
a = 4
}
var a = 2
return fn3
}
var fn = fn1()
fn() //undefined
複製代碼
解密
閉包經典面試題
經典面試題,循環中使用閉包解決 var 定義函數的問題
for ( var i=1; i<=5; i++) {
setTimeout( function timer() {
console.log( i );
}, i*1000 );
}
首先由於 setTimeout 是個異步函數,全部會先把循環所有執行完畢,這時候 i 就是 6 了,因此會輸出一堆 6。
解決辦法兩種,第一種使用閉包(建立的這個當即執行函數就是一個新塊級做用域,並使用了外部的變量i,解析完以後,也不隨着i的最終改變而改變)+當即執行函數
for (var i = 1; i <= 5; i++) {
(function(j) {
setTimeout(function timer() {
console.log(j);
}, j * 1000);
})(i);
}
第三種就是使用 let 定義 i 了
for ( let i=1; i<=5; i++) {
setTimeout( function timer() {
console.log( i );
}, i*1000 );
}
由於對於 let 來講,他會建立一個塊級做用域,至關於剛纔的閉包建立的塊級做用域。
複製代碼
用===
而不用==
。只須要注意兩點
NaN ===NaN//false
===
也都是false
。由於地址不同。高級輪播 // 第一步,循環給按鈕添加點擊事件 //第二步:添加定時器,定時出發,循環輪播,而且進入時暫停輪播 jsbin.com/funumujoqe/…
無縫輪播 說思路就好了,而後說我在工做的時候都不手寫錄播,主要是爲了理解他的原理,而後用別人寫好的輪播庫swiper,這樣工做中的BUG會少一點。
callback 是一種特殊的函數,這個函數被做爲參數傳給另外一個函數去調用。這樣的函數就是回調函數。 舉一個Callback(回調函數)的例子 ,例如:
$button.on('click', function(){})
div.addEventListener('click', function(){})
複製代碼
click 後面的 function 是一個回調,由於「我」沒有調用過這個函數,是瀏覽器在用戶點擊 button 時調用的。
再舉一個使用回調函數的例子
function setClock(callBack){
console.log('1定一個鬧鐘,三秒鐘以後響');
setTimeout(()=>{
console.log('2三秒到了,鬧鐘響了!');
callBack();
},3000)
}
function getUp(){
console.log('3鬧鐘已經響了,該起牀了')
}
setClock(getUp);
複製代碼
回調函數通常只和**異步操做(setTimeOut)**在一塊兒才使用!!!
JavaScript 只在一個線程上運行,JavaScript 同時只能執行一個任務,其餘任務都必須在後面排隊等待。
同步任務主線程上排隊執行的任務。只有前一個任務執行完畢,才能執行後一個任務。
異步任務不進入主線程、而進入任務隊列的任務。只有引擎認爲某個異步任務能夠執行了(好比 Ajax 操做從服務器獲得告終果,或者setTimeOut到時間了(事件循環)),該任務(採用回調函數的形式)纔會進入主線程執行
JavaScript 運行時,除了一個正在運行的主線程,引擎還提供一個任務隊列(task queue),裏面是各類須要當前程序處理的異步任務。
首先,主線程會去執行全部的同步任務。等到同步任務所有執行完,就會去看任務隊列裏面的異步任務。若是知足條件,那麼異步任務就從新進入主線程開始執行,這時它就變成同步任務了。等到執行完,下一個異步任務再進入主線程開始執行。一旦任務隊列清空,程序就結束執行。
異步任務的寫法一般是回調函數。一旦異步任務從新進入主線程,就會執行對應的回調函數。若是一個異步任務沒有回調函數,就不會進入任務隊列,也就是說,不會從新進入主線程,由於沒有用回調函數指定下一步的操做。
JavaScript 引擎怎麼知道異步任務有沒有結果,能不能進入主線程呢?答案就是引擎在不停地檢查,一遍又一遍,只要同步任務執行完了,引擎就會去檢查那些掛起來的異步任務,是否是能夠進入主線程了。這種循環檢查的機制,就叫作事件循環(Event Loop)。
問關於異步、主線程、事件循環(Event Loop)的時候:按照下面回答: 面試官問問題:js是單線程模式的,那麼他是怎麼實現異步操做的? 答:
異步操做的方法: 1.回調函數 2.事件監聽(觸發條件,執行回調函數) 3.ES6:Promise
它們向任務隊列添加定時任務。時間到就添加,而後事件循環就會掃到,掃到了就執行裏面的回調函數。
什麼是Promise? 舉例: $.ajax().then(成功函數,失敗函數)
做用:避免回調嵌套,使回調變的可控
ES6劃入標準標準。Promise如今是js的內置對象。Promise 對象是 JavaScript 的異步操做的解決方案。Promise 可讓異步操做寫起來,就像在寫同步操做的流程,(鏈式使用,then以後能夠繼續then)而沒必要一層層地嵌套回調函數
寫一個Promise異步操做解決方案
function dosomething(){
// Promise 接受函數做爲參數兩個參數,
// resolve: 異步事件成功時調用
// reject: 異步事件失敗時調用
return new Promise((resolve, reject) => {
let result = 異步操做()
// 下面給出承諾,面對不一樣的結果,我會 執行 不一樣的解決方案
if (result === 'success')
resolve('成功數據')
else
reject('失敗數據')
})
}
// 異步操做,模擬機率事件
function 異步操做() {
return Math.random() > 0.5 ? 'success' : 'fail'
}
// 你在dosomething
dosomething()
// 異步操做成功了,那麼咱們打印成功的數據
.then(res => console.log(res))
// 異步操做失敗了,那麼咱們打印失敗的數據
.catch(res => console.log(res))
複製代碼
Sync:同步的意思 Async:異步的意思
傳統模塊化方法:
//module1.js
!function(){
var person = window.person = {
name:"frank",
}
//局部變量person和全局變量person用的是同一個地址
}.call()
複製代碼
雖然不一樣變量,可是是一樣的地址//module2.js
!function(){
var person = person;//即var person = window.person;
console.log(person);
}.call();
複製代碼
//module1.js
!function(){
var person = {
name:"mataotao",
age:18,
};
window.mataotaoGrowUp = function(){
person.age+=1;
return person.age;
};
}.call();
複製代碼
//module2.js
!function(){
var newAge = window.mataotaoGrowUp();
console.log(newAge);//19
}.call();
複製代碼
用閉包的好處: