1. 跨域問題
- jsonp: 利用script標(biāo)簽不受同源策略限制的特點(diǎn), 協(xié)商好一個(gè)callback參數(shù), 當(dāng)然這個(gè)參數(shù)是由請(qǐng)求方定的
- h5新方法: window.postMessage, 首先要有一個(gè)src是另一個(gè)域頁面的ifrmae標(biāo)簽, 并且監(jiān)聽一個(gè)onload事件, 然后在onload函數(shù)里獲取到這個(gè)ifrmae標(biāo)簽, 并通過.contentWindow獲取到另一個(gè)域的頁面的window對(duì)象, 使用這個(gè)window對(duì)象調(diào)用postMessage('XXX')方法, 傳遞數(shù)據(jù), 最后在另一個(gè)域的頁面里, 調(diào)用window.onmessage事件, 通過 事件對(duì)象e.data獲取傳遞的內(nèi)容
- 還可以用服務(wù)器代理的方式, 我用過node和axios實(shí)現(xiàn)過
- window.name: 它有一個(gè)特性就是, 在窗口生命周期沒有結(jié)束之前(未關(guān)閉之前)都只會(huì)共享一個(gè)window.name, 這樣, 當(dāng)我在a.html里設(shè)置了一個(gè)window.name, 頁面跳轉(zhuǎn)b.html后, 這個(gè)window.name不會(huì)改變, 還是a.html里設(shè)置的, 就相當(dāng)于把a(bǔ).html里的數(shù)據(jù)傳到了b.html中. 具體實(shí)現(xiàn):在data.html頁面設(shè)置好window.name利用ifrmae標(biāo)簽載入data.html頁面, 當(dāng)ifrmae載入date.html時(shí)候, 用一個(gè)函數(shù)用來獲取data.html的window.name,
2. 閉包
- js分全局作用域和函數(shù)作用域, 通過作用域鏈, 函數(shù)作用域可以訪問到包含環(huán)境和全局作用域, 全局作用域無法直接訪問到函數(shù)作用域, 只有通過閉包(函數(shù)中的函數(shù)), 將父級(jí)里的數(shù)據(jù)return出去, 然后在把閉包return出去, 閉包能一直訪問到父級(jí)的數(shù)據(jù), 說明父級(jí)里的數(shù)據(jù)一直存在在內(nèi)存中, 所以閉包可能會(huì)導(dǎo)致內(nèi)存泄露
- document.domain: 將兩個(gè)頁面的document.domain設(shè)置成一樣的, 就可以通過ifrmae.contentWindow方法, 訪問到通過ifrmae載入的頁面的window對(duì)象了,也能傳值了
3. css3動(dòng)畫
4. 頁面性能問題解決和分析
- 瀏覽器渲染的過程
-- html轉(zhuǎn)化為dom
-- css轉(zhuǎn)化成cssom
-- 結(jié)合dom和cssom生成渲染樹
-- 生成布局 flow
-- 將布局繪制到頁面上 paint
*注意: 用js獲取offsetXXX, scrollTop等還有g(shù)etComputedStyle()的時(shí)候會(huì)立即出發(fā)回流(reflow), 所以不要吧這些讀操作和寫操作放到一個(gè)語句里
*原則: 樣式表越簡(jiǎn)單, 回流和重繪越快. dom層級(jí)越高, 成本就越高. table成本高與div - 提高性能技巧:
-- 讀操作寫在一起, 寫操作也在一起, 兩種操作不要混在一起
-- 樣式是通過回流(重排)得到的, 最好緩存下
-- 不要一條條改變樣式, 盡量操作class
-- 如果需要對(duì)摸個(gè)元素進(jìn)行多次操作, 可以先將其設(shè)置成display:none, 在隨便操作n次, 完事后再display: block
-- 使用虛擬dom腳本, 例如react或vue
-- window.requestAnimationFrame()調(diào)節(jié)重繪 - js優(yōu)化:
-- 減少作用域鏈查找, 在當(dāng)前執(zhí)行環(huán)境緩存一下包含環(huán)境或全局執(zhí)行環(huán)境的數(shù)據(jù);
-- 字符串拼接盡量避免使用 + , 使用數(shù)組的join();
-- 優(yōu)化循環(huán), 簡(jiǎn)化循環(huán)體, 簡(jiǎn)化終止條件, 比如 for(var i = 0,len= arr.length; i < len; i ++);
-- switch語句更快;
-- 變量聲明提倡 一個(gè)var
-- 使用事件委托js用addlistenerEvent, jq用 on - 減少http請(qǐng)求, 合并css,js, 使用雪碧圖,
- 圖片懶加載
- 靜態(tài)資源用cdn
- 按需加載資源requirejs
5. 用戶交互設(shè)計(jì)理論
6. js事件綁定
7. 遇到比較難的問題, 怎么解決的
8. 移動(dòng)端開發(fā)經(jīng)驗(yàn)
9. canvas
10. js作用域 - 函數(shù)作用域鏈
11.原型繼承:
// Student的構(gòu)造函數(shù)
function Student(props) {
this.name = props.name || 'nonamed'
}
Student.prototype.sayHello = function() {
alert('Hello ' + this.name)
}
// 通過Student擴(kuò)展出PrimaryStudent
function PrimaryStudent() {
Student.call(this, props)
this.grade = props.grade || 1
}
// 聲明空對(duì)象
function F() {}
// 把空對(duì)象原型指向Student
F.prototype = Student.prototype
// 把PrimaryStudent的prototype指向F的實(shí)例化對(duì)象
PrimaryStudent.prototype = new F()
// 修復(fù)PrimaryStudent上的構(gòu)造函數(shù)(constructor)
PrimaryStudent.prototype.constructor = PrimaryStudent
// 驗(yàn)證
var xiaoming = new PrimaryStudent({name: 'zxk', grade: 10})
xiaoming.name // 'zxk'
xiaoming.grade // 10
// 驗(yàn)證原型:
xiaoming.__proto__=== PrimaryStudent.prototype // true
xiaoming.__proto__ .__proto__=== Student.prototype // true
// 驗(yàn)證繼承:
xiaoming instanceof PrimaryStudent // true
xiaoming instanceof Student // true
12 排序算法
// 冒泡排序
function sort(arr) {
for(var i = 0; i < arr.length; i ++) {
for(var j = 0; j < arr.length; j ++) {
if (arr[j] > arr[j + 1]) {
var oldJ = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = oldJ
}
}
}
}
//
13 將[1, 2, [3, [4, 5, [6]]]] => [1, 2, 3, 4, 5, 6]
function transArr(arr, res) {
var res = res || []
for(var i = 0; i < arr.length; i ++) {
if(arr[i] instanceof Array) {
transArr(arr[i], res)
} else {
res.push(arr[i])
}
}
return res
}
14 事件委托
- 好處, 減少dom操作, 提高性能, 為動(dòng)態(tài)插入的元素綁定事件
- 原理事件冒泡, js -> addlistenerEvent, jQ -> on
- 使用on去綁定事件, 通過e.target獲取實(shí)際點(diǎn)擊的元素進(jìn)行相應(yīng)的操作
- jQ使用on去綁定事件, 第二個(gè)參數(shù)填選擇器, 會(huì)將父級(jí)事件代理到這個(gè)選擇器上(使用與動(dòng)態(tài)插入的dom)
15 flex的兼容
- 舊版: display: box; 過渡: display: flex box; 新版: display: flex
- 安卓: 2.3+ display: -webkit-box; 4.4+ display: flex
- ios: 6.1+ display: -webkit-box; 7.1+ display: flex
- pc: ie10支持 flex, -ms形式
- 兼容寫法, 都是向下兼容的, so舊版寫法要放到下邊, 否則就會(huì)不起作用
.box{
display: -webkit-flex; /* 新版本語法: Chrome 21+ */
display: flex; /* 新版本語法: Opera 12.1, Firefox 22+ */
display: -webkit-box; /* 老版本語法: Safari, iOS, Android browser, older WebKit browsers. */
display: -moz-box; /* 老版本語法: Firefox (buggy) */
display: -ms-flexbox; /* 混合版本語法: IE 10 */
}
.flex1 {
-webkit-flex: 1; /* Chrome */
-ms-flex: 1 /* IE 10 */
flex: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */
-webkit-box-flex: 1 /* OLD - iOS 6-, Safari 3.1-6 */
-moz-box-flex: 1; /* OLD - Firefox 19- */
}
16 模塊化requirejs
- 引入require.js
- 配置main.js
require.config({
baseUrl: 'js',
paths: {
app: 'app' // 如果是目錄的話, 這里的名字要和目錄一模一樣, 如果是文件可以不同
}
})
- 在html里引入requirejs和data-main入口
//index.html
<script src="js/requirejs" data-main="main"></script>
- define一個(gè)模塊
// a.js
define(function(){
return {
name: 'a'
}
})
// b.js
define(function(){
return {
name: 'b'
}
})
- 引入模塊
// index.html
<script>
require(['app/a'], function(a) {
console.log(a)
})
setTimeout(function() {
require(['app/b'], function(b) {
console.log(b)
})
}, 3000)
</script>
-
目錄結(jié)構(gòu)
屏幕快照 2018-05-26 下午12.57.10.png
17 css布局
- 左邊固定寬度, 右邊自適應(yīng)
- 左邊: width: 100px; float: left;右邊: width: auto;margin-left: 100px;
- flex: 左邊固定寬度, 右邊: flex: 1,
- 三欄布局左右固定寬度, 中間自適應(yīng)
- 結(jié)構(gòu)是: 左 - 右 - 中, 左: 固定寬度, float: left; 右: 固定寬度float: right; 中: width: auto; margin-left: 左寬, margin-right: 右寬
- css選擇器:
- 類選擇器.class
- id選擇器: #id
- 標(biāo)簽選擇器: p
- 后代選擇器: div p
- 子代選擇器: div>p
- 之后選擇器: div+p
- 屬性選擇器:
- 偽類選擇器:
- nth-child()
- first-child
- :before - after
18 for循環(huán)和定時(shí)器 與 閉包
//瞬間打出0 - 4
for(var i = 0; i < 5; i++) {
console.log(i)
}
for(var i = 0; i < 5; i++) {
setTimeout((function(){ // 自調(diào)用函數(shù), 立即執(zhí)行
console.log(i)
})(), i * 1000)
}
// 順間打出0, 然后每隔一秒打出1-4
for(var i = 0; i < 5; i++) {
(function(i){
setTimeout(function() {
console.log(i)
}, i*1000)
})(i)
}
// 順間打出5, 每隔1秒打出一個(gè)5, 共4個(gè)
for(var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i)
}, i*1000)
}
for(var i = 0; i < 5; i++) {
(function(){
setTimeout(function() {
console.log(i)
}, i * 1000)
})(i)
}
// promise相關(guān)
setTimeout(function() {
console.log(1)
}, 0)
new Promise(function executor(resolve){
console.log(2)
for(var i = 0; i < 1000; i++) {
i == 999 && resolve();
}
console.log(3)
}).then(function() {
console.log(4)
})
console.log(5)
// logs 2 > 3 > 5 > 4 > 1, promise的then()會(huì)放在當(dāng)前tick的最末尾, 但是setTimeout會(huì)把函數(shù)踢到下一輪tick中
18 js高階面試
- 描述js中的繼承和原型鏈, 并舉例
- js并沒有類的概念, 而是通過原型鏈實(shí)現(xiàn)的繼承, 每個(gè)對(duì)象都會(huì)在內(nèi)部引用一個(gè)prototype的對(duì)象, prototype也會(huì)引用自己的原型對(duì)象, 以此類推, 鏈條的末尾是null為原型的對(duì)象, 當(dāng)一個(gè)對(duì)象引用了不屬于自己的屬性時(shí),將會(huì)遍歷原型鏈, 直到找到屬性,或者找到鏈尾 null
- js中的對(duì)象和哈希表
- 對(duì)象本質(zhì)就是一個(gè)hash表, 即鍵值對(duì)的集合, 鍵總是字符串, 由于js是弱類型語言, 當(dāng)你傳入的鍵并非字符串時(shí)候, 也不會(huì)報(bào)錯(cuò), 而是隱式的使用toString()方法,
- 題目:
var foo = new Object() var bar = new Object() var map = new Object() map[foo] = 'foo' map[bar] = 'bar' console.log(map[foo]) // logs: 'bar' 解釋: 由于foo和bar都不是,字符串, js會(huì)隱式的將foo和bar使用toString()方法,由于它們都是空對(duì)象, 所以它們轉(zhuǎn)化的結(jié)果一樣: [Object Object], 也就是說map[bar]覆蓋了map[foo], map[foo]的結(jié)果也是覆蓋后的結(jié)果 - 解釋js中的閉包, 什么是閉包, 它們有什么特性, 如何使用, 舉個(gè)例子
- 閉包是一個(gè)函數(shù), 包含在創(chuàng)建閉包時(shí)處于作用域內(nèi)的所有變量或其他函數(shù). 閉包通過'內(nèi)部函數(shù)'的形式實(shí)現(xiàn)的, 也就是另一個(gè)函數(shù)的主體內(nèi)定義函數(shù)
- 閉包的一個(gè)特性: 閉包可以一直訪問其包含函數(shù)的變量, 也就是說他們會(huì)一直存在在內(nèi)存中不被釋放
- 閉包可以防止變量被內(nèi)存釋放, for循環(huán)和閉包, 創(chuàng)建命名空間防止變量污染
-
描述創(chuàng)建對(duì)象的不同方式, 和各自影響, 提供示例
91527395499_.pic.jpg - 函數(shù)表達(dá)式(var foo = function (){})和函數(shù)語句(function foo(){})定義函數(shù)的區(qū)別?
- 函數(shù)語句可以在定義之前被調(diào)用(通過hoisting技術(shù), 總是使用函數(shù)的最后一個(gè)定義),
function foo(){ return 1} console.log(foo()) // 結(jié)果為: 2 function foo() {return 2}- 函數(shù)表達(dá)式, 則不能在函數(shù)定義之前被調(diào)用
- 將 js源文件里的內(nèi)容封裝到一個(gè)函數(shù)里, 這樣做的重要性和原因?
- 相當(dāng)于為它創(chuàng)建了一個(gè)閉包, 創(chuàng)建一個(gè)私有的命名空間,避免命名沖突
- 為全局變量提供一個(gè)容易引用的別名
(function($){ ... })(jQuery) -
==和===有什么區(qū)別, 舉個(gè)例子-
==比較前會(huì)有隱式轉(zhuǎn)換, 而===是嚴(yán)格的類型比較 -
123 == '123'是成立的結(jié)果為true,123 === '123'是不成立的, 結(jié)果為false
-
- js文件開頭的
use strict是什意思?- js的嚴(yán)格模式, 對(duì)js代碼執(zhí)行嚴(yán)格的解析和錯(cuò)誤處理, 沒有直接調(diào)用者的函數(shù), this指向'undefined'
19 js中的this指向(非嚴(yán)格模式下)
函數(shù)中的this在函數(shù)被定義的時(shí)候并沒有確定下來, 只有函數(shù)被調(diào)用的時(shí)候,才知道它到底指向誰
- 原則1: 一個(gè)函數(shù)沒有被上級(jí)調(diào)用, 那么this指向window
function foo() { console.log(this) // window } foo() - 原則2: 一個(gè)函數(shù)被上級(jí)調(diào)用, 那么this指向上級(jí)函數(shù)
var o = { a: 10, c: function() { console.log(this.a) // 10 console.log(this) // o } } o.c() - 原則3: 一個(gè)函數(shù)中包含多個(gè)對(duì)象, 盡管這個(gè)函數(shù)是被最外層的對(duì)象調(diào)用, 但是this也只會(huì)指向它的上級(jí)
var o = { a: 10, b: { a: 12, fn: function() { console.log(this.a) // 12 console.log(this) // b } } } o.b.fn() - 原則4:
var o = { a: 10, b: { a: 12, fn: function(){ console.log(this.a) // undefined console.log(this) // window } } } var j = o.b.fn j()- 原則5: 構(gòu)造函數(shù)中的this: new 可以改變對(duì)象的this指向 -> new后邊的函數(shù)
function Fn() { this.user = 'zxk' } var a = new Fn() console.log(a.user) // 'zxk' - 原則6: this和return
- 構(gòu)造函數(shù)里return {}, this指向, 這個(gè)對(duì)象
function Fn() { this.name = 'zxk' return { name: 'ret - zxk' } } var xx = new Fn() console.log(xx.name) // 'ret - zxk'- 構(gòu)造函數(shù)里return function(){}, this指向, 這個(gè)函數(shù),但是沒有繼承這個(gè)函數(shù)的prototype, 打印出來的是空
function Fn() { this.name = 'zxk' return function() {} } var xx = new Fn console.log(xx.name) // 啥也沒有- 構(gòu)造函數(shù)里return 非對(duì)象, this指向原來的這個(gè)構(gòu)造函數(shù)
function Fn() { this.name = 'zxk' return 1 } var xx = new Fn() console.log(xx.name) // 'zxk' - call, apply和bind
- 改變函數(shù)的this執(zhí)行, 并沒有繼承原型鏈
- call, apply會(huì)立即執(zhí)行, bind需要()調(diào)用
- 常用的字符串和數(shù)組方法:
- slice(start, end): string直接返回重start開始到end(不包括start)的部分,可以為負(fù)
- splice(index, howmany, item1, item2....,itemn): 從數(shù)組的index開始, 刪howmany個(gè)元素, 替換成item1 - itemn
- concat() 合并兩個(gè)數(shù)組
- substring(start, stop): 返回字符串start到stop(不包含)之間的字符, 不接受負(fù)值, 如果stop為負(fù)值, 那么就取start之前的值
- substr(start, [length]): 返回字符串從start開始的, 共計(jì)length個(gè), 可以接受負(fù)值
20 js經(jīng)典面試題
// code 1
var length = 10;
function fn() {
alert(this.length);
}
var obj = {
length: 5,
method: function() {
fn();
}
};
obj.method(); // 最后相當(dāng)于fn(), 函數(shù)沒有被任何上級(jí)調(diào)用, this指向window
// code 2
var num = 100;
var obj = {
num: 200,
inner: {
num: 300,
print: function() {
console.log(this.num);
}
}
};
obj.inner.print(); //300, this指向inner
var func = obj.inner.print;
func(); //100 默認(rèn)綁定,this指向window
obj.inner.print(); //300 thi指向inner
(obj.inner.print = obj.inner.print)(); //100 this指向window
// code 3
function foo() {
console.log(this.a);
}
var obj2 = { a: 42, foo: foo };
var obj1 = { a: 2, obj2: obj2 };
obj1.obj2.foo(); // 42 this指向他的直接上級(jí)obj2
var obj3 = { a: 2 };
foo.call(obj3); // 2, this指向call的參數(shù)obj3
var bar = function() {
foo.call(obj3);
};
bar(); // 2, 就相當(dāng)于foo.call(obj3)
setTimeout(bar, 100); // 2, bar的this指向window, 但是執(zhí)行bar的時(shí)候, 其實(shí)執(zhí)行的是foo.cal(obj3),
bar.call(window); // 2, 同上
var obj4 = { a: 3, foo: foo };
obj2.foo(); // 42, this指向obj2
obj4.foo(); // 3, this指向obj4
obj2.foo.call(obj4); // 3 this指向call的參數(shù)obj4
obj4.foo.call(obj2); // 42 this指向call參數(shù)obj2
// code 4
function foo() {
console.log(this.a);
}
var obj = {
a: 2,
foo: foo
};
var a = "oops, global"; // a是全局對(duì)象的屬性
setTimeout(obj.foo, 100); // "oops, global", setTimeout里的this都會(huì)指向window, 相當(dāng)于var fun = obj.foo, fun()
obj.foo(); // 2, this指向obj
// code 5 (new綁定)
function foo(a) {
this.a = a;
}
var bar = new foo(2);
console.log(bar.a); // 2 new可以改變this, 讓bar的this指向foo
var obj1 = { foo: foo };
var obj2 = {};
obj1.foo(2);
console.log(obj1.a); // 2, foo(2)的this指向obj1, this.a相當(dāng)于給obj1添加a屬性
obj1.foo.call(obj2, 3);
console.log(obj2.a); // 3, obj1的this指向obj2并傳參數(shù), 相當(dāng)于給obj2, 添加a屬性
var bar = new obj1.foo(4);
console.log(obj1.a); // 2
console.log(bar.a); // 4
// code 6
function foo() {
console.log(this.a);
}
var a = 2;
// 如果你把null或者undefined作為this的綁定對(duì)象傳入call\apply\bind,這些值在調(diào)用的時(shí)候會(huì)被忽略,實(shí)際應(yīng)用的是默認(rèn)綁定規(guī)則。
foo.call(null); // 2
var bar = foo.bind(null);
bar(); // 2
foo.apply(undefined); // 2
// code 7 箭頭函數(shù)
function foo() {
return a => console.log(this.a);
}
var obj1 = { a: 2 };
var obj2 = { a: 3 };
var bar = foo.call(obj1);
bar.call(obj2); // 2 箭頭函數(shù)是根據(jù)外層(函數(shù)或者全局)作用域來決定this。并且綁定后無法修改。
-
- 字符串倒序
function reverseString(str) { var strArray = str.split(""); // 使用空字符串來分割成字符數(shù)組 return strArray.reverse().join(""); // 反轉(zhuǎn)并連接 } reverseString("hello"); -
- 下面代碼執(zhí)行結(jié)果是啥, 如何實(shí)現(xiàn)每隔1秒輸出1 - 5
for (var i = 1; i <= 5; i++) { setTimeout(function() { console.log(i); }, i * 1000); }每個(gè)1秒秒輸出6共輸出5個(gè), 循環(huán)終止條件是i <= 5, i最終值是6的時(shí)候, 循環(huán)才結(jié)束, setTimeout會(huì)把函數(shù)踢出本次任務(wù)隊(duì)列, 等循環(huán)結(jié)束后, 才打印console.log(i), i那個(gè)時(shí)候已經(jīng)是6了,
- 套個(gè)閉包, 并把每次循環(huán)的i緩存起來,并傳進(jìn)閉包就ok
- 用let聲明 變量: 每次循環(huán)都會(huì)重新聲明一個(gè)i
for(let i = 0; i < 5; i++) { setTimeout(function() { console.log(i) }, i*1000) } -
- 代碼執(zhí)行結(jié)果
3 + "3" // '33' "23" > "3" // false var b = true && 2; // undefined "abc123".slice(2, -1) // 'c12' "abc123".substring(2, -1) // 'ab' //如果 start or stop 是負(fù)數(shù)或 NaN,會(huì)把它當(dāng)成 0 對(duì)待;如果 start > stop,則會(huì)交換這兩個(gè)參數(shù)
var foo = 1,
bar = 2,
j,
test;
test = function(j) {
j = 5;
var bar = 5;
console.log(bar); // 5
foo = 5;
};
test(10);
console.log(foo); // 5 改變的全局變量
console.log(bar); // 2 由于函數(shù)作用域?qū)θ肿饔糜虻碾[藏,所以只有在test函數(shù)內(nèi)部,bar=5,并不能影響到全局中的bar
console.log(j); // undefined test(10)函數(shù)調(diào)用的時(shí)候,是函數(shù)內(nèi)部的參數(shù)j接收到了10,但是它也是函數(shù)作用域內(nèi)的變量,并不會(huì)改變?nèi)肿饔糜蛑械膉。
if (!("sina" in window)) {
var sina = 1;
}
console.log("sina:", sina); // undefined
// 變量提升: js會(huì)把所有的通過var聲明的全局變量, 提升到最頂層, 所有sina液在if之前就存在了, 也不會(huì)走if()分支
// 相當(dāng)于
var sina
f (!("sina" in window)) {
sina = 1;
}
console.log("sina:", sina); // undefined
function SINA() {
return 1;
}
var SINA;
console.log(typeof SINA); // function
// 重復(fù)聲明被忽略了, 所以var沒有生效
- 數(shù)組去重, 帶obj的元素
var arr = [2, [1,2], 3, "2", "a", "b", "a", [1, 2]]
function quchong(arr) {
var map = {}
var res = []
arr.forEach(item => {
if(!map[JSON.stringify(item)]) {
res.push(item)
map[JSON.stringify(item)] = 1
}
})
return res
}
console.log(quchong(arr))
function foo() {
"use strict";
console.log(this.a);
}
function bar() {
console.log(this.a);
}
var a = "this is a 'a'";
bar(); // "this is a 'a'"
foo(); // "TypeError: Cannot read property 'a' of undefined
alert(a); // 輸出函數(shù)體
a(); // 10
var a = 3;
function a() {
alert(10);
}
alert(a); // 3
a = 6;
a(); // 報(bào)錯(cuò)a不是一個(gè)function
alert(a); // undefined
a(); // a is not a function
var a = 3;
var a = function() {
// 函數(shù)表達(dá)式
alert(10);
};
alert(a); // 輸出函數(shù)體
a = 6;
a(); // a is not a function 因?yàn)閍已經(jīng)賦值成6了
- 查看字符串中最多的元素
function findMax(str) {
var map = {} // 存儲(chǔ)str每個(gè)元素和對(duì)應(yīng)數(shù)量的對(duì)象
var max = {num: 0} // 存儲(chǔ)最大值的對(duì)象
for(var i in str) {
if(map[str[i]]) {
map[str[i]] ++
} else {
map[str[i]] = 1
}
if(map[str[i]] > max.num) {
max.num = map[str[i]]
max.key = str[i]
}
}
return max
}
var max = findMax(_str)
console.log(max)
21 數(shù)組方法和字符串方法
- 數(shù)組方法:
- pop(): 刪除數(shù)組最后刪一個(gè)元素, 并返回這個(gè)元素
- push(): 在數(shù)組末尾添加一個(gè)元素, 并返回?cái)?shù)組的length

