A. "string"
B. "function"
C. "object"
D. "null"
A. 輸入:typeof {"x":1} 輸出:"object"
B. 輸入:typeof 1 輸出:"number"
C. 輸入:typeof [{x:1}] 輸出:"array"
D. 輸入:typeof NaN 輸出:"number"
A. undefined
B. null
C. array
D. object
A. Boolean
B. undefined
C. Symbol
D. Array
A. 數(shù)據(jù)類型分為基本數(shù)據(jù)類型和引用數(shù)據(jù)類型
B. JavaScript一共有8種數(shù)據(jù)類型
C. Object是引用數(shù)據(jù)類型,且只存儲(chǔ)于堆(heap)中
D. BigInt是可以表示任意精度整數(shù)的基本數(shù)據(jù)類型,存儲(chǔ)于棧(stack)中
答案
DCADC
A. null instanceof Object
B. null===undefined
C. null==undefined
D. NaN==NaN
A. Symbol.for('a')===Symbol.for('a')
B. Symbol('a')===Symbol('a')
C. NaN===NaN
D. {}==={}
var a=1;
var b=[];
var c='';
var d=true;
A. (a || b)===true
B. (b && c)===true
C. (c && d)===true
D. (d || a)===true
A. T
B. F
A. console.log([]===[]);
B. console.log(undefined==0);
C. console.log(undefined==false);
D. console.log(false=='');
A. console.log("12"===12)
B. console.log (NaN===NaN)
C. console.log (typeof(null)===typeof(window))
D. console.log ([1,2,3]===[1,2,3])
注意瀏覽器環(huán)境與node環(huán)境的差別,比如C選項(xiàng)
A. Number('a')==Number('a')
B. -1==true
C. 3 + '2'===5
D. ![]==''
答案
CADADCD
A. Math.round(7.25)
B. Math.ceil(7.25)
C. round(7.25)
D. Math.rnd(7.25)
A. Math.floor(Math.random()*6)
B. Math.floor(Math.random()*10)
C. Math.floor(Math.random()*11)
D. Math.ceil(Math.random()*10)
A. Math.floor(Math.random()*6)
B. Math.floor(Math.random()*7)
C. Math. floor(Math.random()*8)
答案
A CD(注意D) C
A. T
B. F
A. match()
B. indexOf()
C. search()
D. concat()
答案
A BC
A. {name:"xiaoming",age,"student"}
B. {"name":"xiaoming","age":"student"}
C. {"xiaoming","student"}
D. ["xiaoming","student"]
const fn=function(){}
const res=JSON.stringify(fn)
const num=123
const res=JSON.stringify(num)
const res=JSON.stringify(NaN)
const b=true
const res=JSON.stringify(b)
A. 'function'、'123'、'NaN'、'true'
B. undefined、'123'、undefined、'true'
C. undefined、'123'、'null'、'true'
D. undefined、'123'、'null'、undefined
答案
BC
A. push
B. concat
C. sort
D. shift
A. slice
B. splice
C. sort
D. unshift
A. push
B. pop
C. shift
D. unshift
A. push
B. pop
C. unshift
D. splice
A. concat
B. splice
C. slice
D. join
A. concat
B. shift
C. filter
D. map
A. push
B. slice
C. splice
D. sort
// (1)
const newNums=Array.from(new Set(nums))
// (2)
const newNums=nums.filter((n, i)=> {
return nums.indexOf(n)===i
})
// (3)
const newNums=nums.forEach((n, i)=> {
return nums.indexOf(n)===i
})
// (4)
const newNums=nums.reduce((acc, n, i)=> {
return [].concat(acc, nums.indexOf(n)===i ? n : []
)
})
A. (1)、(2)、(3)、(4)
B. (1)、(3)、(4)
C. (1)、(2)、(4)
D. (1)、(4)
答案
BAABB
BBC
A. 123
B. 123a
C. d123
D. 123def
A. test
B. match
C. exec
D. compile
A. str.replace(`/\s*/g,""`)
B. str.replace(`/^\s|\s$/g,""`)
C. str.replace(`/^\s*/, ""`)
D. str.replace(`/(\s*$)/g, ""`)
答案
CBA
A. encodeURI
B. parseFloat
C. round
D. eval
A. 遵循嚴(yán)格模式:"use strict"
B. 將js腳本放在頁面頂部,加快渲染頁面
C. 將js腳本成組打包,減少請(qǐng)求,盡量減少使用閉包
D. 使用非阻塞方式下載js腳本,最小化重繪(repaint)和回流(reflow)
A. parseFloat方法:該方法將一個(gè)字符串轉(zhuǎn)換成對(duì)應(yīng)的小數(shù)
B. isNaN方法:該方法用于檢測(cè)參數(shù)是否為數(shù)值型,如果是,返回true,否則,返回false。
C. escape方法: 該方法返回對(duì)一個(gè)字符串編碼后的結(jié)果字符串
D. eval方法:該方法將某個(gè)參數(shù)字符串作為一個(gè)JavaScript執(zhí)行題
A. chrome
B. Safari
C. 搜狗瀏覽器
D. Firefox
// A
var formatDate=getDate()
// B
var formatDate=new Date()
// C
var formatDate=function (date) {
var y=date.getFullYear();
var m=date.getMonth() + 1;
var d=date.getDate();
return y + '-' + m + '-' + d;
};
// D
var formatDate=function (date) {
var y=date.getFullYear();
var m=date.getMonth() + 1;
m=m < 10 ? '0' + m : m;
var d=date.getDate();
d=d < 10 ? ('0' + d) : d;
return y + '-' + m + '-' + d;
};
A. 需要對(duì)元素進(jìn)行復(fù)雜的操作時(shí),可以先隱藏(display:"none"),操作完成后再顯示
B. 需要?jiǎng)?chuàng)建多個(gè)DOM節(jié)點(diǎn)時(shí),使用DocumentFragment創(chuàng)建完后一次性的加入document
C. 盡量避免用table布局(table元素一旦觸發(fā)回流就會(huì)導(dǎo)致table里所有的其它元素回流)
D. 盡量不要使用 css 屬性簡寫,如:用border-width, border-style, border-color代替border
答案
CBBDDD
A. eval
B. apply
C. bind
D. call
A. 在使用new實(shí)例化對(duì)象時(shí), this指向這個(gè)實(shí)例對(duì)象
B. 將對(duì)象的方法賦值給變量A。執(zhí)行A()時(shí) 該方法中的this指向這個(gè)對(duì)象。
C. 在函數(shù)定義時(shí),this指向全局變量
D. 在瀏覽器下的全局范圍內(nèi),this指向全局對(duì)象
A. call與apply都屬于Function.prototype的一個(gè)方法,所以每個(gè)function實(shí)例都有call、apply屬性
B. 兩者傳遞的參數(shù)不同,call函數(shù)第一個(gè)參數(shù)都是要傳入給當(dāng)前對(duì)象的對(duì)象,apply不是
C. apply傳入的是一個(gè)參數(shù)數(shù)組,也就是將多個(gè)參數(shù)組合成為一個(gè)數(shù)組傳入
D. call傳入的則是直接的參數(shù)列表。call 方法可將一個(gè)函數(shù)的對(duì)象上下文從初始的上下文改變?yōu)橛?thisObj 指定的新對(duì)象。
答案
AAB
// (1)
function getName() {
name='javascript'
}
getName()
// (2)
const elements={
button: document.getElementById('button')
};
function removeButton() {
document.body.removeChild(elements.button);
}
removeButton()
// (3)
let timer=setInterval(()=> {
const node=document.querySelector('#node')
if(node) {
clearInterval(timer)
}
}, 1000);
A. (1)、(2)、(3)
B. (2)、(3)
C. (1)、(3)
D. (1)、(2)
A. 沒有清理的DOM元素引用
B. 被遺忘的定時(shí)器
C. 事件偵聽沒有移除
D. 局部變量不用時(shí),沒有設(shè)為null
A. 增加一定的內(nèi)存消耗
B. 使用不當(dāng)可能會(huì)導(dǎo)致內(nèi)存泄漏
C. 可以使用閉包模擬私有方法
D. 閉包會(huì)改動(dòng)對(duì)象的原型鏈
答案
DDD
A. 原型鏈繼承
B. 構(gòu)造函數(shù)繼承
C. 組合繼承
D. 關(guān)聯(lián)繼承
A. T
B. F
A. 通過原型鏈繼承的屬性和對(duì)象自己定義的屬性等效
B. 通過原型鏈可以模擬對(duì)象的私有屬性
C. 在對(duì)象上訪問不存在的屬性時(shí),會(huì)依次遍歷整條原型鏈
D. 所有 JavaScript 中的對(duì)象都是位于原型鏈頂端的 `Object` 的實(shí)例
答案
DBC
A. jsonp
B. cookie
C. localStorage
D. sessionStorage
答案
A
A. event.preventDefault()
B. event.prevent()
C. event.drag()
D. event.drop()
A. mouseover
B. click
C. mouseleave
D. mousemove
A. stopDeafault()
B. stopPropagation()
C. preventDefault()
D. preventDefaultEven()
目標(biāo) -> 捕獲 -> 冒泡
冒泡 -> 目標(biāo) -> 捕獲
目標(biāo) -> 冒泡 -> 捕獲
捕獲 -> 目標(biāo) -> 冒泡
A. onchange:用戶改變域的內(nèi)容
B. onkeypress:某個(gè)鍵盤的鍵被按下或按住
C. onmousedown:某個(gè)鼠標(biāo)按鍵被按下
D. onblur:元素獲得焦點(diǎn)
答案
ACCDD
A. parentObj.firstChild
B. parentObj.children
C. neborNode.previousSibling
D. neborNode.siblings
A. appendChild(parentNode,newNode);
B. append(parentNode,newNode);
C. parentNode.append(newNode);
D. parentNode.appendChild(newNode);
A. Array
B. Object
C. String
D. Function
A. appendChild(parentNode,newNode);
B. append(parentNode,newNode);
C. parentNode.append(newNode);
D. parentNode.appendChild(newNode);
答案
DDBD
outline
visiblity
font-size
background-color
答案
C
A. 每隔60秒調(diào)用一次updateClock()
B. 每隔60毫秒調(diào)用一次updateClock()
C. 每隔60分鐘調(diào)用一次updateClock()
D. 每分鐘調(diào)用60次updateClock()
A. Geolocation.watchPosition()
B. Geolocation.getCurrentPosition()
C. Geolocation.getPosition()
D. Geolocation.Position()
A. 等待1000秒后,再彈出一個(gè)對(duì)話框
B. 等待1秒鐘后彈出一個(gè)對(duì)話框
C. 每隔一秒鐘彈出一個(gè)對(duì)話框
D. 語句報(bào)錯(cuò),語法有問題
答案
BBC
A. 箭頭函數(shù)沒有原型屬性
B. 箭頭函數(shù)不綁定this,會(huì)捕獲其所在的上下文的this值,作為自己的this值
C. 箭頭函數(shù)可以作為構(gòu)造函數(shù),使用new
D. 箭頭函數(shù)不綁定arguments,取而代之用rest參數(shù)解決
A. 函數(shù)體內(nèi)this的指向是定義時(shí)所在的對(duì)象,而不是使用時(shí)所在的對(duì)象
B. 箭頭函數(shù)內(nèi)不能使用arguments對(duì)象
C. 箭頭函數(shù)不能使用yield命令
D. 可以使用new創(chuàng)建一個(gè)箭頭函數(shù)的實(shí)例
答案
CD
Promise.all([]).then((res)=> {
console.log('all');
});
Promise.race([]).then((res)=> {
console.log('race');
});
A. all 和 race 都會(huì)被輸出
B. all 和 race 都不會(huì)被輸出
C. all 會(huì)被輸出,而 race 不會(huì)被輸出
D. all 不會(huì)被輸出,race 會(huì)被輸出
A. Promise
B. Generator
C. async
D. Proxy
A. Pending
B. Pause
C. Fulfilled
D. Rejected
答案
CDB
let [a,b, c,d, e]="hello";
A. e="hello";
B. 其它都為undefined
C. 當(dāng)中 a="h", b="e";
D. 語法報(bào)錯(cuò)
答案
C
A. push
B. concat
C. splice
D. map
A. const a=0xa1
B. const a=076
C. const a=0b21
D. const a=7e2
(1)function
(2) object
(3) null
(4) array
(5) NaN
(6) bigint
(7) regexp
(8) undefined
A. (1)、(2)、(3)、(4)、(5)、(6)、(7)、(8)
B. (1)、(2)、(3)、(8)
C. (1)、(2)、(8)
D. (1)、(2)、(6)、(8)
A. typeof 'string'
B. String('string').toString()
C. 'string'.split('').sort().join('')
D. (function(string){return string})('string')
E. JSON.parse('{"string":"string"}').string
A. parseInt(46.8) `==` parseFloat(46.8)
B. NaN `!==` NaN
C. isNaN('abc') `==` NaN
D. typeof NaN `===` 'number'
A. Array.from(A)
B. [].slice.apply(A)
C. [...A]
D. [].map.call(A, o=> o)
A. null==undefined
B. null===undefined
C. null===null
D. NaN==null
E. NaN===NaN
F. Infinity + 1 !==Infinity
答案
AC ABD D ABDE BD ABCD AC
function Person() { } var person=new Person();
A. 每一個(gè)原型都有一個(gè)constructor屬性指向關(guān)聯(lián)的構(gòu)造函數(shù)。
B. 每一個(gè)對(duì)象都有一個(gè)prototype屬性。
C. Object.getPrototypeOf(person)===Person.prototype
D. person.constructor===Person
A. process.nextTick
B. promise
C. setTimeout
D. setInterval
答案
ACD AB
A. let聲明的變量值和類型都可以改變
B. const聲明的常量不可以改變
C. 兩者都不存在變量提升,同時(shí)存在暫時(shí)性死區(qū),只能在聲明的位置后面使用
D. const可以先聲明再初始化,可以后賦值
A. Promise.all在所有給定的promise都fulfilled后才返回結(jié)果
B. Promise.race在給定的promise中,某個(gè)fulfilled后才返回結(jié)果
C. promise.then的回調(diào)函數(shù)中,可以返回一個(gè)新的promise
D. 對(duì)于一個(gè)向后臺(tái)獲取數(shù)據(jù)已經(jīng)產(chǎn)生結(jié)果的promise:p1,再次調(diào)用p1.then,不會(huì)去重新發(fā)起請(qǐng)求獲取數(shù)據(jù)
答案
ABC CD
document.body.style.['background-color']='#fff'
document.body.style.setProperty('background-color', '#fff')
document.body.style='background-color': #fff'
document.body.style.fontSize='14px'
A. event.cancelBubble=true;
B. event.stopPropagation();
C. event.preventDefault();
D. return false;
答案
BCD ABD
var x=typeof x
var res=typeof typeof x;
console.log(x, res)
var arr=[];
console.log(typeof arr, Object.prototype.toString.call(arr));
// case 1
function showCase(value) {
switch(value) {
case 'A':
console.log('Case A');
break;
case 'B':
console.log('Case B');
break;
case undefined:
console.log('Case undefined');
break;
default:
console.log('Case default');
}
}
showCase(new String('A'));
// case 2
function showCase(value) {
switch(value) {
case 'A':
console.log('Case A');
break;
case 'B':
console.log('Case B');
break;
case undefined:
console.log('Case undefined');
break;
default:
console.log('Case default');
}
}
showCase(String('A'));
<html>
<body>
<p id="demo"></p>
<script type="text/javascript">
var x=10;
var y="10";
document.getElementById("demo").innerHTML=Boolean(x==y);
</script>
</body>
</html>
function funcA(x){
var temp=4;
function funcB(y){
document.write( ++x + y + (temp--));
}
funcB(5);
}
funcA(6)
var varArr=function(i,j,str) {
return j==0 ? str : varArr(i,--j,(str+=" " + i[j]));
}
var arr=new Array('apple','orange','peach','lime');
var str=varArr(arr,arr.length,"");
alert(str);
function greetingMaker(greeting) {
function addName(name) {
greeting=greeting.split(' ').reverse().join("-");
return greeting + " " + name;
}
return addName;
}
var daytimeGreeting=greetingMaker("Good Day to you");
alert(daytimeGreeting(name));
String.prototype.GetNum=function() {
var regEx=/[^\d]/g;
return this.replace(regEx, '');
};
var str="a1b2c3";
str=str.GetNum();
alert(str);
function sum(a, b) {
return a + b;
}
sum(1, "2");
var str="我非常喜歡編程";
str.length=3;
console.log(str);
let number=0;
console.log(number++);
console.log(++number);
console.log(number);
function nums(a, b) {
if (a > b)
console.log('a is bigger')
else
console.log('b is bigger')
return a + b
}
console.log(nums(4, 2))
console.log(nums(1, 2))
function side(arr) {
arr[0]=arr[2];
}
function func1(a, b, c=3) {
c=10;
side(arguments);
console.log(a + b + c);
}
function func2(a, b, c) {
c=10;
side(arguments);
console.log(a + b + c);
}
func1(1, 1, 1);
func2(1, 1, 1);
var a=3;
var b=new Number(3);
var c=3;
console.log(a==b);
console.log(a===b);
console.log(b===c);
var a=[];
a.push(1, 2);
a.shift(3, 4);
a.concat([5, 6]);
a.splice(0, 1, 2);
var a={}, b='123', c=123;
a[b]='b';
a[c]='c';
console.log(a[b]);
// example 2
var a={}, b=Symbol('123'), c=Symbol('123');
a[b]='b';
a[c]='c';
console.log(a[b]);
// example 3
var a={}, b={key:'123'}, c={key:'456'};
a[b]='b';
a[c]='c';
console.log(a[b]);
null==undefined
0.1 + 0.2==0.3
typeof NaN
typeof Function
typeof Object
typeof {}
'a' + 1
'a' - 1
Function instanceof Object
Object instanceof Function
var array=[]
for(var i=0; i < 3; i++) {
array.push(()=> i)
}
var newArray=array.map(el=> el())
console.log(newArray)
function a(m, n) {
var b=function (l) {
return l <=m ? l * b(l + 1) : 1;
}
return b(m - n + 1);
}
console.log(a(4, 2));
console.log(typeof undefined==typeof NULL);
console.log(typeof function () {}==typeof class {});
var a=10
var b={
age: 11
}
function fn(x,y) {
--y.age;
return --x;
}
fn(a,b)
var number=4;
var numberFactorial=(function (number){
return (number===0)? 1: number* factorial(number-1)
})(number)
console.log(numberFactorial)
var array=[]
for(var i=0; i < 3; i++) {
array.push(()=> i)
}
var newArray=array.map(el=> el())
console.log(newArray)
function addToList(item, list) {
return list.push(item)
}
const result=addToList("nowcoder", ["hello"])
console.log(result)
const first=()=> { console.log('first'); return false; }
const second=()=> { console.log('second'); return true; }
console.log( first() && second() );
console.log( second() || first() );
var s='12ab3cd', arr=s.split(/\d/);
console.log(arr[3],arr[4])
function getAge(...args) {
console.log(typeof args);
}
getAge(21);
var arr=[1,2,3];
arr.push(arr.shift())
console.log(arr[1],arr[2])
題目解析:this指向題目解析及擴(kuò)展[3]
關(guān)于this還可以看看:可能是最好的 this 解析了...
var x=1;
var obj={
x: 3,
fun:function () {
var x=5;
return this.x;
}
};
var fun=obj.fun;
console.log( obj.fun(), fun() );
var a=5;
function test() {
a=0;
alert(a);
alert(this.a);
var a;
alert(a);
}
new test();
function fun () {
return ()=> {
return ()=> {
return ()=> {
console.log(this.name)
}
}
}
}
var f=fun.call({name: 'foo'})
var t1=f.call({name: 'bar'})()()
var t2=f().call({name: 'baz'})()
var t3=f()().call({name: 'qux'})
let obj1={
a: 1,
foo: ()=> {
console.log(this.a)
}
}
// log1
obj1.foo()
const obj2=obj1.foo
// log2
obj2()
const Person=(name="wang",age=10)=> {
this.name=name;
this.age=age;
return this.name +' is '+ this.age + 'years old'
}
let result=new Person('zhang',11)
console.log(result)
var person={
age: 18,
getAge: function() {
return this.age;
}
};
var getAge=person.getAge
getAge()
var name='global';
var obj={
name: 'local',
foo: function(){
this.name='foo';
}.bind(window)
};
var bar=new obj.foo();
setTimeout(function() {
console.log(window.name);
}, 0);
console.log(bar.name);
var bar3=bar2=bar;
bar2.name='foo2';
console.log(bar3.name);
var obj={
name:"zhangsan",
sayName:function(){
console.info(this.name);
}
}
var wfunc=obj.sayName;
obj.sayName();
wfunc();
var name="lisi";
obj.sayName();
wfunc();
var name='test'
var a={
name: 'ass',
getName: function() {
return this.name;
}
}
var b=a.getName;
b();
const promiseA=Promise.resolve('a')
promiseA. then((res)=> {
console.log(res)
}).then((res)=> {
console.log(res)
})
const promiseB=Promise.resolve('b')
promiseB. then((res)=> {
console.log(res)
})
promiseB. then((res)=> {
console.log(res)
})
setTimeout(()=> {
console.log(1)
}, 0)
const P=new Promise((resolve, reject)=> {
console.log(2)
setTimeout(()=> {
resolve()
console.log(3)
}, 0)
})
P.then(()=> {
console.log(4)
})
console.log(5)
setTimeout(function(){
console.log(1);
}, 0)
new Promise(function(resolve){
console.log(2);
resolve();
console.log(3);
}).then(function(){
console.log(4);
})
console.log(5);
(async ()=> {
console.log(1);
setTimeout(()=> {
console.log(2);
}, 0);
await new Promise((resolve, reject)=> {
console.log(3);
}).then(()=> {
console.log(4);
});
console.log(5);
})();
new Promise((resolve)=> {
console.log('1')
resolve()
console.log('2')
}).then(()=> {
console.log('3')
})
setTimeout(()=> {
console.log('4')
})
console.log('5')
var p1=new Promise(function(resolve, reject){
resolve("2")
})
setTimeout(function(){
console.log("1")
},10)
p1.then(function(value){
console.log(value)
})
setTimeout(function(){
console.log("3")
},0)
setTimeout(function() {
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');
});
setTimeout(function() {
console.log(1)
},0)
new Promise(function executor(resolve){
console.log(2)
for (var i=0; i<10000; i++) {
i - 9999 && resolve()
}
console.log(3)
}).then(function() {
console.log(4)
})
console.log(5)
<div class="outer">
<div class="inner"></div>
</div>
對(duì)應(yīng)的js代碼如下:
var outer=document.querySelector('.outer');
var inner=document.querySelector('.inner');
function onClick() {
console.log('click');
setTimeout(function() {
console.log('timeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise');
});
outer.setAttribute('data-random', Math.random());
}
inner.addEventListener('click', onClick);
outer.addEventListener('click', onClick);
當(dāng)點(diǎn)擊class為inner的div塊時(shí),控制臺(tái)依次輸出結(jié)果是什么?10. 下面程序的輸出結(jié)果是?
(async ()=> {
console.log(1);
setTimeout(()=> {
console.log(2);
}, 0);
await new Promise((resolve, reject)=> {
console.log(3);
}).then(()=> {
console.log(4);
});
console.log(5);
})();
setTimeout(()=> console.log('a'));
Promise.resolve().then(
()=> console.log('b’);
).then(
()=> Promise.resolve('c').then(
(data)=> {
setTimeout(()=> console.log('d'));
console.log('f');
return data;
}
)
).then(data=> console.log(data));
console.log('one');
setTimeout(function() { console.log('two'); }, 0);
Promise.resolve()
.then(function() { console.log('three'); })
console.log('four');
setTimeout(function () {
console.log(C)
},0)
console.log('D')
new Promise(function(resolve){
console.log('E')
resolve()
console.log('F')
}).then(function() {
console.log('G')
})
console.log('H')
function log(msg, time) {
return new Promise((resolve)=> {
setTimeout(()=> {
console.log(msg);
resolve();
}, time);
});
}
則下面三段代碼輸出的結(jié)果是:
// 第一段代碼:
(async ()=> {
for (let i=0; i < 5; i++) {
await log(i, 1000);
}
})();
// 第二段代碼:
(async ()=> {
[ 1, 2, 3, 4 ].forEach(async (i)=> {
await log(i, 1000);
});
})();
// 第三段代碼:
(async ()=> {
for (const i of [ 1, 2, 3, 4 ]) {
await log(i, 1000);
}
})();
關(guān)于原型JS:看完這篇文章,徹底了解 “原型” & “this”
傳送門: 原型與原型鏈題目解析[4]
function Fn1(name) {
if(name){
this.name=name;
}
}
Fn1.prototype.name="jack"
let a=new Fn1();
console.log('a:', a.name);
function Fn2(name) {
this.name=name;
}
Fn2.prototype.name="jack"
let b=new Fn2();
console.log('b:', b.name);
var Foo=(function() {
var x=0;
function Foo() {}
Foo.prototype.increment=function() {
++x;
console.log(x);
};
return Foo;
})();
var a=new Foo();
a.increment();
a.increment();
var b=new Foo();
a.increment();
var name='Jay'
function Person(name){
this.name=name;
console.log(this.name)
}
var a=Person('Tom')
console.log(name)
console.log(a)
var b=new Person('Michael')
console.log(b)
class A{}
class B extends A{}
const a=new A()
const b=new B()
a.__proto__
b.__proto__
B. __proto__
B. prototype.__proto__
b.__proto__.__proto__
function test() {
getName=function() {
Promise.resolve().then(()=> console.log(0));
console.log(1);
};
return this;
}
test.getName=function() {
setTimeout(()=> console.log(2), 0);
console.log(3);
};
test.prototype.getName=function() {
console.log(4);
};
var getName=function() {
console.log(5);
};
function getName() {
console.log(6);
}
test.getName();
getName();
test().getName();
getName();
new test.getName();
new test().getName();
new new test().getName();
var tmp={};
var A=function() {};
A. prototype=tmp;
var a=new A();
A. prototype={};
var b=Object.create(tmp);
b.constructor=A. constructor;
console.log(a instanceof A);
console.log(b instanceof A);
function Foo(){}
Foo.prototype.z=3;
var obj=new Foo();
console.info(obj.z)
obj.z=10;
console.info(obj.z);
delete obj.z;
console.info(obj.z);
const Book={
price: 32
}
const book=Object.create(Book);
book.type='Math';
delete book.price;
delete book.type;
console.log(book.price);
console.log(book.type);
function sayHello() {
console.log(name);
console.log(age);
var name="Tom";
let age=18;
}
sayHello();
for (var i=0; i < 3; i++) {
setTimeout(_=> {
console.log(i)
})
}
for (let i=0; i < 3; i++) {
setTimeout(_=> {
console.log(i)
})
}
console.log(a);
var a='a';
console.log(b);
let b='b';
var foo="Hello";
(function(){
var bar=" World";
alert(foo + bar);
})();
alert(foo + bar);
var a=10;
(function () {
console.log(a)
a=5
console.log(window.a)
var a=20;
console.log(a)
})()
const a=10
function runFunction() {
const a=20
console.log('inside', a)
}
runFunction()
console.log('outside', a)
"use strict"
var name='Jay'
var person={
name: 'Wang',
pro: {
name: 'Michael',
getName: function () {
return this.name
}
}
}
console.log(person.pro.getName)
var people=person.pro.getName
console.log(people())
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
var elements=document.getElementsByTagName("li");
for (var i=0;i<elements.length;i++){
elements[i].onclick=function( ){
alert(i);
};
}
compute(10,100);
var compute=function(A,B) {
console.info(A * B) ;
};
function compute(A,B){
console.info(A + B);
}
function compute(A,B){
console.info((A + B)*2);
}
compute(2,10);
meili()
function meili() {
console.log("meili")
}
mogu()
var mogu=function() {
console.log("mogu")
}
// 片段1
check('first');
function check(ars){
console.log(ars);
}
// 片段2
check('second');
var check=function(ars){
console.log(ars);
}
const student={name: 'ZhangSan'}
Object.defineProperty(student, 'age', {value: 22})
console.log(student)
console.log(Object.keys(student))
function * cb(x, y) {
for(let i=Math.ceil(x); i <=y; i++) {
yield i;
}
}
var a=cb(6, 9);
console.log(a.next());
console.log(a.next());
function fn(...args) {
console.log(typeof args);
}
fn(21);
Promise.reject(0)
.catch(e=> e)
.catch(e=> console.log(e))
class Person {
constructor (name) {
this.name=name;
}
greet () {
console.log(`Hi, my name is ${this.name}`);
}
greetDelay (time) {
setTimeout(()=> {
console.log(`Hi, my name is ${this.name}`);
}, time);
}
}
function getPersonInfo (one, two, three) {
console.log(one)
console.log(two)
console.log(three)
}
const person='Lydia'
const age=21
getPersonInfo `${person} is ${age} years old`
// module.js
export default ()=> "Hello world"
export const name="nowcoder"
// index.js
import * as data from "./module"
console.log(data)
// a.js
let a=1
let b={}
setTimeout(()=> {
a=2
b.b=2
}, 100)
module.exports={ a, b }
// b.js
const a=require('./a')
console.log(a.a)
console.log(a.b)
setTimeout(()=> {
console.log(a.a)
console.log(a.b)
}, 500)
<div id="box1">
<div id="box2">
content
</div>
</div>
<script>
const $=document.querySelector.bind(document);
const box1=$('#box1');
const box2=$('#box2');
box1.addEventListener('click', ()=>{
console.log('box1 true');
}, true);
box1.addEventListener('click', ()=>{
console.log('box1 false');
}, false);
box2.addEventListener('click', ()=>{
console.log('box2 true');
}, true);
box2.addEventListener('click', ()=>{
console.log('box2 false');
}, false);
</script>
$(function () {
function fn1( value ) {
alert( value );
}
function fn2( value ) {
fn1("A");
return false;
}
var callbacks=$.Callbacks();
callbacks.add( fn1 );
callbacks.fire( "B" );
callbacks.add( fn2 );
callbacks.fire( "C" );
})
<html>
<head>
<script type="text/javascript" src="/jquery/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("button").click(function(){
$("<b>Hello World!</b>").______("p");
});
});
</script>
</head>
<body>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
<button>在每個(gè)p元素的結(jié)尾添加內(nèi)容</button>
</body>
</html>
<div id="box1">
<div id="box2">
content
</div>
</div>
<script>
const $=document.querySelector.bind(document);
const box1=$('#box1');
const box2=$('#box2');
box1.addEventListener('click', ()=> {
console.log('box1 true');
}, true);
box1.addEventListener('click', ()=> {
console.log('box1 false');
}, false);
box2.addEventListener('click', ()=> {
console.log('box2 true');
}, true);
box2.addEventListener('click', ()=> {
console.log('box2 false');
}, false);
</script>
小夕:https://juejin.im/post/5cab0c45f265da2513734390
1. 基本類型有哪幾種?null 是對(duì)象嗎?基本數(shù)據(jù)類型和復(fù)雜數(shù)據(jù)類型存儲(chǔ)有什么區(qū)別?
2. typeof 是否正確判斷類型? instanceof呢? instanceof 的實(shí)現(xiàn)原理是什么?
首先 typeof 能夠正確的判斷基本數(shù)據(jù)類型,但是除了 null, typeof null輸出的是對(duì)象。
但是對(duì)象來說,typeof 不能正確的判斷其類型, typeof 一個(gè)函數(shù)可以輸出 'function',而除此之外,輸出的全是 object,這種情況下,我們無法準(zhǔn)確的知道對(duì)象的類型。
instanceof可以準(zhǔn)確的判斷復(fù)雜數(shù)據(jù)類型,但是不能正確判斷基本數(shù)據(jù)類型。
instanceof 是通過原型鏈判斷的,A instanceof B, 在A的原型鏈中層層查找,是否有原型等于B.prototype,如果一直找到A的原型鏈的頂端(null;即Object.__proto__.__proto__),仍然不等于B.prototype,那么返回false,否則返回true.
instanceof的實(shí)現(xiàn)代碼:
// L instanceof R function instance_of(L, R) {//L 表示左表達(dá)式,R 表示右表達(dá)式 var O=R.prototype;// 取 R 的顯式原型 L=L.__proto__; // 取 L 的隱式原型 while (true) { if (L===null) //已經(jīng)找到頂層 return false; if (O===L) //當(dāng) O 嚴(yán)格等于 L 時(shí),返回 true return true; L=L.__proto__; //繼續(xù)向上一層原型鏈查找 } }
3. for of , for in 和 forEach,map 的區(qū)別。
PS: Object.keys():返回給定對(duì)象所有可枚舉屬性的字符串?dāng)?shù)組。
關(guān)于forEach是否會(huì)改變?cè)瓟?shù)組的問題,有些小伙伴提出了異議,為此我寫了代碼測(cè)試了下(注意數(shù)組項(xiàng)是復(fù)雜數(shù)據(jù)類型的情況)。 除了forEach之外,map等API,也有同樣的問題。
let arry=[1, 2, 3, 4]; arry.forEach((item)=> { item *=10; }); console.log(arry); //[1, 2, 3, 4] arry.forEach((item)=> { arry[1]=10; //直接操作數(shù)組 }); console.log(arry); //[ 1, 10, 3, 4 ] let arry2=[ { name: "Yve" }, { age: 20 } ]; arry2.forEach((item)=> { item.name=10; }); console.log(arry2);//[ { name: 10 }, { age: 20, name: 10 } ]
如還不了解 iterator 接口或 for...of, 請(qǐng)先閱讀ES6文檔: Iterator 和 for...of 循環(huán)
更多細(xì)節(jié)請(qǐng)戳: github.com/YvetteLau/B…
4. 如何判斷一個(gè)變量是不是數(shù)組?
function fn() { console.log(Array.isArray(arguments)); //false; 因?yàn)閍rguments是類數(shù)組,但不是數(shù)組 console.log(Array.isArray([1,2,3,4])); //true console.log(arguments instanceof Array); //fasle console.log([1,2,3,4] instanceof Array); //true console.log(Object.prototype.toString.call(arguments)); //[object Arguments] console.log(Object.prototype.toString.call([1,2,3,4])); //[object Array] console.log(arguments.constructor===Array); //false arguments.constructor=Array; console.log(arguments.constructor===Array); //true console.log(Array.isArray(arguments)); //false } fn(1,2,3,4);
5. 類數(shù)組和數(shù)組的區(qū)別是什么?
類數(shù)組:
1)擁有l(wèi)ength屬性,其它屬性(索引)為非負(fù)整數(shù)(對(duì)象中的索引會(huì)被當(dāng)做字符串來處理);
2)不具有數(shù)組所具有的方法;
類數(shù)組是一個(gè)普通對(duì)象,而真實(shí)的數(shù)組是Array類型。
常見的類數(shù)組有: 函數(shù)的參數(shù) arguments, DOM 對(duì)象列表(比如通過 document.querySelectorAll 得到的列表), jQuery 對(duì)象 (比如 $("div")).
類數(shù)組可以轉(zhuǎn)換為數(shù)組:
//第一種方法 Array.prototype.slice.call(arrayLike, start); //第二種方法 [...arrayLike]; //第三種方法: Array.from(arrayLike);
PS: 任何定義了遍歷器(Iterator)接口的對(duì)象,都可以用擴(kuò)展運(yùn)算符轉(zhuǎn)為真正的數(shù)組。
Array.from方法用于將兩類對(duì)象轉(zhuǎn)為真正的數(shù)組:類似數(shù)組的對(duì)象(array-like object)和可遍歷(iterable)的對(duì)象。
6.==和===有什么區(qū)別?
===不需要進(jìn)行類型轉(zhuǎn)換,只有類型相同并且值相等時(shí),才返回 true.
==如果兩者類型不同,首先需要進(jìn)行類型轉(zhuǎn)換。具體流程如下:
let person1={ age: 25 } let person2=person1; person2.gae=20; console.log(person1===person2); //true,注意復(fù)雜數(shù)據(jù)類型,比較的是引用地址
思考: []==![]
我們來分析一下: []==![] 是true還是false?
7. ES6中的class和ES5的類有什么區(qū)別?
8. 數(shù)組的哪些API會(huì)改變?cè)瓟?shù)組?
修改 原數(shù)組的API有:
splice/reverse/fill/copyWithin/sort/push/pop/unshift/shift
不修改 原數(shù)組的API有:
slice/map/forEach/every/filter/reduce/entries/find
注: 數(shù)組的每一項(xiàng)是簡單數(shù)據(jù)類型,且未直接操作數(shù)組的情況下(稍后會(huì)對(duì)此題重新作答)。
9. let、const 以及 var 的區(qū)別是什么?
10. 在JS中什么是變量提升?什么是暫時(shí)性死區(qū)?
變量提升就是變量在聲明之前就可以使用,值為undefined。
在代碼塊內(nèi),使用 let/const 命令聲明變量之前,該變量都是不可用的(會(huì)拋出錯(cuò)誤)。這在語法上,稱為“暫時(shí)性死區(qū)”。暫時(shí)性死區(qū)也意味著 typeof 不再是一個(gè)百分百安全的操作。
typeof x; // ReferenceError(暫時(shí)性死區(qū),拋錯(cuò)) let x; 復(fù)制代碼 typeof y; // 值是undefined,不會(huì)報(bào)錯(cuò)
暫時(shí)性死區(qū)的本質(zhì)就是,只要一進(jìn)入當(dāng)前作用域,所要使用的變量就已經(jīng)存在了,但是不可獲取,只有等到聲明變量的那一行代碼出現(xiàn),才可以獲取和使用該變量。
11. 如何正確的判斷this? 箭頭函數(shù)的this是什么?
this的綁定規(guī)則有四種:默認(rèn)綁定,隱式綁定,顯式綁定,new綁定.
測(cè)試下是否已經(jīng)成功Get了此知識(shí)點(diǎn)(瀏覽器執(zhí)行環(huán)境):
var number=5; var obj={ number: 3, fn1: (function () { var number; this.number *=2; number=number * 2; number=3; return function () { var num=this.number; this.number *=2; console.log(num); number *=3; console.log(number); } })() } var fn1=obj.fn1; fn1.call(null); obj.fn1(); console.log(window.number);
12. 詞法作用域和this的區(qū)別。
13. 談?wù)勀銓?duì)JS執(zhí)行上下文棧和作用域鏈的理解。
執(zhí)行上下文就是當(dāng)前 JavaScript 代碼被解析和執(zhí)行時(shí)所在環(huán)境, JS執(zhí)行上下文棧可以認(rèn)為是一個(gè)存儲(chǔ)函數(shù)調(diào)用的棧結(jié)構(gòu),遵循先進(jìn)后出的原則。
作用域鏈: 無論是 LHS 還是 RHS 查詢,都會(huì)在當(dāng)前的作用域開始查找,如果沒有找到,就會(huì)向上級(jí)作用域繼續(xù)查找目標(biāo)標(biāo)識(shí)符,每次上升一個(gè)作用域,一直到全局作用域?yàn)橹埂?/p>
14. 什么是閉包?閉包的作用是什么?閉包有哪些使用場(chǎng)景?
閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù),創(chuàng)建閉包最常用的方式就是在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)。
閉包的作用有:
15. call、apply有什么區(qū)別?call,aplly和bind的內(nèi)部是如何實(shí)現(xiàn)的?
call 和 apply 的功能相同,區(qū)別在于傳參的方式不一樣:
call核心:
Function.prototype.call=function (context) { /** 如果第一個(gè)參數(shù)傳入的是 null 或者是 undefined, 那么指向this指向 window/global */ /** 如果第一個(gè)參數(shù)傳入的不是null或者是undefined, 那么必須是一個(gè)對(duì)象 */ if (!context) { //context為null或者是undefined context=typeof window==='undefined' ? global : window; } context.fn=this; //this指向的是當(dāng)前的函數(shù)(Function的實(shí)例) let rest=[...arguments].slice(1);//獲取除了this指向?qū)ο笠酝獾膮?shù), 空數(shù)組slice后返回的仍然是空數(shù)組 let result=context.fn(...rest); //隱式綁定,當(dāng)前函數(shù)的this指向了context. delete context.fn; return result; } //測(cè)試代碼 var foo={ name: 'Selina' } var name='Chirs'; function bar(job, age) { console.log(this.name); console.log(job, age); } bar.call(foo, 'programmer', 20); // Selina programmer 20 bar.call(null, 'teacher', 25); // 瀏覽器環(huán)境: Chirs teacher 25; node 環(huán)境: undefined teacher 25
apply:
apply的實(shí)現(xiàn)和call很類似,但是需要注意他們的參數(shù)是不一樣的,apply的第二個(gè)參數(shù)是數(shù)組或類數(shù)組.
Function.prototype.apply=function (context, rest) { if (!context) { //context為null或者是undefined時(shí),設(shè)置默認(rèn)值 context=typeof window==='undefined' ? global : window; } context.fn=this; let result; if(rest===undefined || rest===null) { //undefined 或者 是 null 不是 Iterator 對(duì)象,不能被 ... result=context.fn(rest); }else if(typeof rest==='object') { result=context.fn(...rest); } delete context.fn; return result; } var foo={ name: 'Selina' } var name='Chirs'; function bar(job, age) { console.log(this.name); console.log(job, age); } bar.apply(foo, ['programmer', 20]); // Selina programmer 20 bar.apply(null, ['teacher', 25]); // 瀏覽器環(huán)境: Chirs programmer 20; node 環(huán)境: undefined teacher 25
bind
bind 和 call/apply 有一個(gè)很重要的區(qū)別,一個(gè)函數(shù)被 call/apply 的時(shí)候,會(huì)直接調(diào)用,但是 bind 會(huì)創(chuàng)建一個(gè)新函數(shù)。當(dāng)這個(gè)新函數(shù)被調(diào)用時(shí),bind() 的第一個(gè)參數(shù)將作為它運(yùn)行時(shí)的 this,之后的一序列參數(shù)將會(huì)在傳遞的實(shí)參前傳入作為它的參數(shù)。
Function.prototype.bind=function(context) { if(typeof this !=="function"){ throw new TypeError("not a function"); } let self=this; let args=[...arguments].slice(1); function Fn() {}; Fn.prototype=this.prototype; let bound=function() { let res=[...args, ...arguments]; //bind傳遞的參數(shù)和函數(shù)調(diào)用時(shí)傳遞的參數(shù)拼接 context=this instanceof Fn ? this : context || this; return self.apply(context, res); } //原型鏈 bound.prototype=new Fn(); return bound; } var name='Jack'; function person(age, job, gender){ console.log(this.name , age, job, gender); } var Yve={name : 'Yvette'}; let result=person.bind(Yve, 22, 'enginner')('female');
16. new的原理是什么?通過new的方式創(chuàng)建對(duì)象和通過字面量創(chuàng)建有什么區(qū)別?
new:
function new(func) { let target={}; target.__proto__=func.prototype; let res=func.call(target); if (res && typeof(res)=="object" || typeof(res)=="function") { return res; } return target; }
字面量創(chuàng)建對(duì)象,不會(huì)調(diào)用 Object構(gòu)造函數(shù), 簡潔且性能更好;
new Object() 方式創(chuàng)建對(duì)象本質(zhì)上是方法調(diào)用,涉及到在proto鏈中遍歷該方法,當(dāng)找到該方法后,又會(huì)生產(chǎn)方法調(diào)用必須的 堆棧信息,方法調(diào)用結(jié)束后,還要釋放該堆棧,性能不如字面量的方式。
通過對(duì)象字面量定義對(duì)象時(shí),不會(huì)調(diào)用Object構(gòu)造函數(shù)。
17. 談?wù)勀銓?duì)原型的理解?
在 JavaScript 中,每當(dāng)定義一個(gè)對(duì)象(函數(shù)也是對(duì)象)時(shí)候,對(duì)象中都會(huì)包含一些預(yù)定義的屬性。其中每個(gè)函數(shù)對(duì)象都有一個(gè)prototype 屬性,這個(gè)屬性指向函數(shù)的原型對(duì)象。使用原型對(duì)象的好處是所有對(duì)象實(shí)例共享它所包含的屬性和方法。
18. 什么是原型鏈?【原型鏈解決的是什么問題?】
原型鏈解決的主要是繼承問題。
每個(gè)對(duì)象擁有一個(gè)原型對(duì)象,通過 proto (讀音: dunder proto) 指針指向其原型對(duì)象,并從中繼承方法和屬性,同時(shí)原型對(duì)象也可能擁有原型,這樣一層一層,最終指向 null(Object.proptotype.__proto__ 指向的是null)。這種關(guān)系被稱為原型鏈 (prototype chain),通過原型鏈一個(gè)對(duì)象可以擁有定義在其他對(duì)象中的屬性和方法。
構(gòu)造函數(shù) Parent、Parent.prototype 和 實(shí)例 p 的關(guān)系如下:(p.__proto__===Parent.prototype)
19. prototype 和 __proto__ 區(qū)別是什么?
prototype是構(gòu)造函數(shù)的屬性。
__proto__ 是每個(gè)實(shí)例都有的屬性,可以訪問 [[prototype]] 屬性。
實(shí)例的__proto__ 與其構(gòu)造函數(shù)的prototype指向的是同一個(gè)對(duì)象。
function Student(name) { this.name=name; } Student.prototype.setAge=function(){ this.age=20; } let Jack=new Student('jack'); console.log(Jack.__proto__); //console.log(Object.getPrototypeOf(Jack));; console.log(Student.prototype); console.log(Jack.__proto__===Student.prototype);//true
20. 使用ES5實(shí)現(xiàn)一個(gè)繼承?
組合繼承(最常用的繼承方式)
function SuperType(name) { this.name=name; this.colors=['red', 'blue', 'green']; } SuperType.prototype.sayName=function() { console.log(this.name); } function SubType(name, age) { SuperType.call(this, name); this.age=age; } SubType.prototype=new SuperType(); SubType.prototype.constructor=SubType; SubType.prototype.sayAge=function() { console.log(this.age); }
其它繼承方式實(shí)現(xiàn),可以參考《JavaScript高級(jí)程序設(shè)計(jì)》
21. 什么是深拷貝?深拷貝和淺拷貝有什么區(qū)別?
淺拷貝是指只復(fù)制第一層對(duì)象,但是當(dāng)對(duì)象的屬性是引用類型時(shí),實(shí)質(zhì)復(fù)制的是其引用,當(dāng)引用指向的值改變時(shí)也會(huì)跟著變化。
深拷貝復(fù)制變量值,對(duì)于非基本類型的變量,則遞歸至基本類型變量后,再復(fù)制。深拷貝后的對(duì)象與原來的對(duì)象是完全隔離的,互不影響,對(duì)一個(gè)對(duì)象的修改并不會(huì)影響另一個(gè)對(duì)象。
實(shí)現(xiàn)一個(gè)深拷貝:
function deepClone(obj) { //遞歸拷貝 if(obj===null) return null; //null 的情況 if(obj instanceof RegExp) return new RegExp(obj); if(obj instanceof Date) return new Date(obj); if(typeof obj !=='object') { //如果不是復(fù)雜數(shù)據(jù)類型,直接返回 return obj; } /** * 如果obj是數(shù)組,那么 obj.constructor 是 [Function: Array] * 如果obj是對(duì)象,那么 obj.constructor 是 [Function: Object] */ let t=new obj.constructor(); for(let key in obj) { //如果 obj[key] 是復(fù)雜數(shù)據(jù)類型,遞歸 t[key]=deepClone(obj[key]); } return t; }
22. 防抖和節(jié)流的區(qū)別是什么?防抖和節(jié)流的實(shí)現(xiàn)。
防抖和節(jié)流的作用都是防止函數(shù)多次調(diào)用。區(qū)別在于,假設(shè)一個(gè)用戶一直觸發(fā)這個(gè)函數(shù),且每次觸發(fā)函數(shù)的間隔小于設(shè)置的時(shí)間,防抖的情況下只會(huì)調(diào)用一次,而節(jié)流的情況會(huì)每隔一定時(shí)間調(diào)用一次函數(shù)。
防抖(debounce): n秒內(nèi)函數(shù)只會(huì)執(zhí)行一次,如果n秒內(nèi)高頻事件再次被觸發(fā),則重新計(jì)算時(shí)間
function debounce(func, wait, immediate=true) { let timer; // 延遲執(zhí)行函數(shù) const later=(context, args)=> setTimeout(()=> { timer=null;// 倒計(jì)時(shí)結(jié)束 if (!immediate) { func.apply(context, args); //執(zhí)行回調(diào) context=args=null; } }, wait); let debounced=function (...params) { let context=this; let args=params; if (!timer) { timer=later(context, args); if (immediate) { //立即執(zhí)行 func.apply(context, args); } } else { clearTimeout(timer); //函數(shù)在每個(gè)等待時(shí)延的結(jié)束被調(diào)用 timer=later(context, args); } } debounced.cancel=function () { clearTimeout(timer); timer=null; }; return debounced; };
防抖的應(yīng)用場(chǎng)景:
節(jié)流(throttle): 高頻事件在規(guī)定時(shí)間內(nèi)只會(huì)執(zhí)行一次,執(zhí)行一次后,只有大于設(shè)定的執(zhí)行周期后才會(huì)執(zhí)行第二次。
//underscore.js function throttle(func, wait, options) { var timeout, context, args, result; var previous=0; if (!options) options={}; var later=function () { previous=options.leading===false ? 0 : Date.now() || new Date().getTime(); timeout=null; result=func.apply(context, args); if (!timeout) context=args=null; }; var throttled=function () { var now=Date.now() || new Date().getTime(); if (!previous && options.leading===false) previous=now; var remaining=wait - (now - previous); context=this; args=arguments; if (remaining <=0 || remaining > wait) { if (timeout) { clearTimeout(timeout); timeout=null; } previous=now; result=func.apply(context, args); if (!timeout) context=args=null; } else if (!timeout && options.trailing !==false) { // 判斷是否設(shè)置了定時(shí)器和 trailing timeout=setTimeout(later, remaining); } return result; }; throttled.cancel=function () { clearTimeout(timeout); previous=0; timeout=context=args=null; }; return throttled; };
函數(shù)節(jié)流的應(yīng)用場(chǎng)景有:
23. 取數(shù)組的最大值(ES5、ES6)
// ES5 的寫法 Math.max.apply(null, [14, 3, 77, 30]); // ES6 的寫法 Math.max(...[14, 3, 77, 30]); // reduce [14,3,77,30].reduce((accumulator, currentValue)=>{ return accumulator=accumulator > currentValue ? accumulator : currentValue });
24. ES6新的特性有哪些?
25. setTimeout倒計(jì)時(shí)為什么會(huì)出現(xiàn)誤差?
setTimeout() 只是將事件插入了“任務(wù)隊(duì)列”,必須等當(dāng)前代碼(執(zhí)行棧)執(zhí)行完,主線程才會(huì)去執(zhí)行它指定的回調(diào)函數(shù)。要是當(dāng)前代碼消耗時(shí)間很長,也有可能要等很久,所以并沒辦法保證回調(diào)函數(shù)一定會(huì)在 setTimeout() 指定的時(shí)間執(zhí)行。所以, setTimeout() 的第二個(gè)參數(shù)表示的是最少時(shí)間,并非是確切時(shí)間。
HTML5標(biāo)準(zhǔn)規(guī)定了 setTimeout() 的第二個(gè)參數(shù)的最小值不得小于4毫秒,如果低于這個(gè)值,則默認(rèn)是4毫秒。在此之前。老版本的瀏覽器都將最短時(shí)間設(shè)為10毫秒。另外,對(duì)于那些DOM的變動(dòng)(尤其是涉及頁面重新渲染的部分),通常是間隔16毫秒執(zhí)行。這時(shí)使用 requestAnimationFrame() 的效果要好于 setTimeout();
26. 為什么 0.1 + 0.2 !=0.3 ?
0.1 + 0.2 !=0.3 是因?yàn)樵谶M(jìn)制轉(zhuǎn)換和進(jìn)階運(yùn)算的過程中出現(xiàn)精度損失。
下面是詳細(xì)解釋:
JavaScript使用 Number 類型表示數(shù)字(整數(shù)和浮點(diǎn)數(shù)),使用64位表示一個(gè)數(shù)字。
圖片說明:
計(jì)算機(jī)無法直接對(duì)十進(jìn)制的數(shù)字進(jìn)行運(yùn)算, 需要先對(duì)照 IEEE 754 規(guī)范轉(zhuǎn)換成二進(jìn)制,然后對(duì)階運(yùn)算。
1.進(jìn)制轉(zhuǎn)換
0.1和0.2轉(zhuǎn)換成二進(jìn)制后會(huì)無限循環(huán)
0.1 -> 0.0001100110011001...(無限循環(huán)) 0.2 -> 0.0011001100110011...(無限循環(huán))
但是由于IEEE 754尾數(shù)位數(shù)限制,需要將后面多余的位截掉,這樣在進(jìn)制之間的轉(zhuǎn)換中精度已經(jīng)損失。
2.對(duì)階運(yùn)算
由于指數(shù)位數(shù)不相同,運(yùn)算時(shí)需要對(duì)階運(yùn)算 這部分也可能產(chǎn)生精度損失。
按照上面兩步運(yùn)算(包括兩步的精度損失),最后的結(jié)果是
0.0100110011001100110011001100110011001100110011001100
結(jié)果轉(zhuǎn)換成十進(jìn)制之后就是 0.30000000000000004。
27. promise 有幾種狀態(tài), Promise 有什么優(yōu)缺點(diǎn) ?
promise有三種狀態(tài): fulfilled, rejected, pending.
Promise 的優(yōu)點(diǎn):
Promise 的缺點(diǎn):
28. Promise構(gòu)造函數(shù)是同步還是異步執(zhí)行,then中的方法呢 ?promise如何實(shí)現(xiàn)then處理 ?
Promise的構(gòu)造函數(shù)是同步執(zhí)行的。then 中的方法是異步執(zhí)行的。
29. Promise和setTimeout的區(qū)別 ?
Promise 是微任務(wù),setTimeout 是宏任務(wù),同一個(gè)事件循環(huán)中,promise.then總是先于 setTimeout 執(zhí)行。
30. 如何實(shí)現(xiàn) Promise.all ?
要實(shí)現(xiàn) Promise.all,首先我們需要知道 Promise.all 的功能:
Promise.all=function (promises) { return new Promise((resolve, reject)=> { let index=0; let result=[]; if (promises.length===0) { resolve(result); } else { function processValue(i, data) { result[i]=data; if (++index===promises.length) { resolve(result); } } for (let i=0; i < promises.length; i++) { //promises[i] 可能是普通值 Promise.resolve(promises[i]).then((data)=> { processValue(i, data); }, (err)=> { reject(err); return; }); } } }); }
31.如何實(shí)現(xiàn) Promise.finally ?
不管成功還是失敗,都會(huì)走到finally中,并且finally之后,還可以繼續(xù)then。并且會(huì)將值原封不動(dòng)的傳遞給后面的then.
Promise.prototype.finally=function (callback) { return this.then((value)=> { return Promise.resolve(callback()).then(()=> { return value; }); }, (err)=> { return Promise.resolve(callback()).then(()=> { throw err; }); }); }
32. 什么是函數(shù)柯里化?實(shí)現(xiàn) sum(1)(2)(3) 返回結(jié)果是1,2,3之和。
函數(shù)柯里化是把接受多個(gè)參數(shù)的函數(shù)變換成接受一個(gè)單一參數(shù)(最初函數(shù)的第一個(gè)參數(shù))的函數(shù),并且返回接受余下的參數(shù)而且返回結(jié)果的新函數(shù)的技術(shù)。
function sum(a) { return function(b) { return function(c) { return a+b+c; } } } console.log(sum(1)(2)(3)); // 6
引申:實(shí)現(xiàn)一個(gè)curry函數(shù),將普通函數(shù)進(jìn)行柯里化:
<!DOCTYPE>聲明位于位于HTML文檔中的第一行,處于 <html>標(biāo)簽之前。告知瀏覽器的解析器,用什么文檔標(biāo)準(zhǔn)解析這個(gè)文檔。DOCTYPE不存在或格式不正確會(huì)導(dǎo)致文檔以兼容模式呈現(xiàn)。
標(biāo)準(zhǔn)模式的排版 和JS運(yùn)作模式都是以該瀏覽器支持的最高標(biāo)準(zhǔn)運(yùn)行。在兼容模式中,頁面以寬松的向后兼容的方式顯示,模擬老式瀏覽器的行為以防止站點(diǎn)無法工作。
HTML5 不基于 SGML,因此不需要對(duì)DTD進(jìn)行引用,但是需要doctype來規(guī)范瀏覽器的行為(讓瀏覽器按照它們應(yīng)該的方式來運(yùn)行);
而HTML4.01基于SGML,所以需要對(duì)DTD進(jìn)行引用,才能告知瀏覽器文檔所使用的文檔類型。**
首先:CSS規(guī)范規(guī)定,每個(gè)元素都有display屬性,確定該元素的類型,每個(gè)元素都有默認(rèn)的display值,如div的display默認(rèn)值為“block”,則為“塊級(jí)”元素;span默認(rèn)display屬性值為“inline”,是“行內(nèi)”元素。
(1)行內(nèi)元素有:a b span img input select strong(強(qiáng)調(diào)的語氣)
(2)塊級(jí)元素有:div ul ol li dl dt dd h1 h2 h3 h4…p
(3)常見的空元素:
<img><input><link><meta>
鮮為人知的是:
<area><base><col><command><embed><keygen><param><source><track><wbr>
4.頁面導(dǎo)入樣式時(shí),使用link和@import有什么區(qū)別?
link屬于XHTML標(biāo)簽,除了加載CSS外,還能用于定義RSS, 定義rel連接屬性等作用;而@import是CSS提供的,只能用于加載CSS;
頁面被加載的時(shí),link會(huì)同時(shí)被加載,而@import引用的CSS會(huì)等到頁面被加載完再加載;
import是CSS2.1 提出的,只在IE5以上才能被識(shí)別,而link是XHTML標(biāo)簽,無兼容問題;
主要分成兩部分:渲染引擎(layout engineer或Rendering Engine)和JS引擎。
渲染引擎:負(fù)責(zé)取得網(wǎng)頁的內(nèi)容(HTML、XML、圖像等等)、整理訊息(例如加入CSS等),以及計(jì)算網(wǎng)頁的顯示方式,然后會(huì)輸出至顯示器或打印機(jī)。瀏覽器的內(nèi)核的不同對(duì)于網(wǎng)頁的語法解釋會(huì)有不同,所以渲染的效果也不相同。所有網(wǎng)頁瀏覽器、電子郵件客戶端以及其它需要編輯、顯示網(wǎng)絡(luò)內(nèi)容的應(yīng)用程序都需要內(nèi)核。
JS引擎則:解析和執(zhí)行javascript來實(shí)現(xiàn)網(wǎng)頁的動(dòng)態(tài)效果。
最開始渲染引擎和JS引擎并沒有區(qū)分的很明確,后來JS引擎越來越獨(dú)立,內(nèi)核就傾向于只指渲染引擎。
Trident內(nèi)核:IE,MaxThon,TT,The World,360,搜狗瀏覽器等。[又稱MSHTML]
Gecko內(nèi)核:Netscape6及以上版本,F(xiàn)F,MozillaSuite/SeaMonkey等
Presto內(nèi)核:Opera7及以上。 [Opera內(nèi)核原為:Presto,現(xiàn)為:Blink;]
Webkit內(nèi)核:Safari,Chrome等。 [ Chrome的:Blink(WebKit的分支)]
移除的元素:
純表現(xiàn)的元素:basefont,big,center,font, s,strike,tt,u;
對(duì)可用性產(chǎn)生負(fù)面影響的元素:frame,frameset,noframes;
用正確的標(biāo)簽做正確的事情。
html語義化讓頁面的內(nèi)容結(jié)構(gòu)化,結(jié)構(gòu)更清晰,便于對(duì)瀏覽器、搜索引擎解析;
即使在沒有樣式CSS情況下也以一種文檔格式顯示,并且是容易閱讀的;
搜索引擎的爬蟲也依賴于HTML標(biāo)記來確定上下文和各個(gè)關(guān)鍵字的權(quán)重,利于SEO;
使閱讀源代碼的人對(duì)網(wǎng)站更容易將網(wǎng)站分塊,便于閱讀維護(hù)理解。
在用戶沒有連網(wǎng)時(shí),可以正常訪問站點(diǎn)或應(yīng)用,在用戶與網(wǎng)絡(luò)連接時(shí)更新用戶機(jī)器上的緩存文件。
原理:HTML5的離線存儲(chǔ)是基于一個(gè)新建的.appcache文件的緩存機(jī)制(不是存儲(chǔ)技術(shù)),通過這個(gè)文件上的解析清單離線存儲(chǔ)資源,這些資源就會(huì)像cookie一樣被存儲(chǔ)了下來。之后當(dāng)網(wǎng)絡(luò)在處于離線狀態(tài)下時(shí),瀏覽器會(huì)通過被離線存儲(chǔ)的數(shù)據(jù)進(jìn)行頁面展示。
如何使用:
頁面頭部像下面一樣加入一個(gè)manifest的屬性;
在cache.manifest文件的編寫離線存儲(chǔ)的資源;
CACHE MANIFEST
#v0.11
CACHE:
js/app.js
css/style.css
NETWORK:
resourse/logo.png
FALLBACK:
/ /offline.html
在離線狀態(tài)時(shí),操作window.applicationCache進(jìn)行需求實(shí)現(xiàn)。
在線的情況下,瀏覽器發(fā)現(xiàn)html頭部有manifest屬性,它會(huì)請(qǐng)求manifest文件,如果是第一次訪問app,那么瀏覽器就會(huì)根據(jù)manifest文件的內(nèi)容下載相應(yīng)的資源并且進(jìn)行離線存儲(chǔ)。如果已經(jīng)訪問過app并且資源已經(jīng)離線存儲(chǔ)了,那么瀏覽器就會(huì)使用離線的資源加載頁面,然后瀏覽器會(huì)對(duì)比新的manifest文件與舊的manifest文件,如果文件沒有發(fā)生改變,就不做任何操作,如果文件改變了,那么就會(huì)重新下載文件中的資源并進(jìn)行離線存儲(chǔ)。
離線的情況下,瀏覽器就直接使用離線存儲(chǔ)的資源。
iframe會(huì)阻塞主頁面的Onload事件;
搜索引擎的檢索程序無法解讀這種頁面,不利于SEO;
iframe和主頁面共享連接池,而瀏覽器對(duì)相同域的連接有限制,所以會(huì)影響頁面的并行加載。
使用iframe之前需要考慮這兩個(gè)缺點(diǎn)。如果需要使用iframe,最好是通過javascript
動(dòng)態(tài)給iframe添加src屬性值,這樣可以繞開以上兩個(gè)問題。
label標(biāo)簽來定義表單控制間的關(guān)系,當(dāng)用戶選擇該標(biāo)簽時(shí),瀏覽器會(huì)自動(dòng)將焦點(diǎn)轉(zhuǎn)到和標(biāo)簽相關(guān)的表單控件上。
<label for="Name">Number:</label>
<input type=“text“name="Name" id="Name"/>
<label>Date:<input type="text" name="B"/></label>
WebSocket、也可以調(diào)用localstorge、cookies等本地存儲(chǔ)方式,還可以使用頁面的路有參數(shù)傳遞
localstorge另一個(gè)瀏覽上下文里被添加、修改或刪除時(shí),它都會(huì)觸發(fā)一個(gè)事件,
我們通過監(jiān)聽事件,控制它的值來進(jìn)行頁面信息通信;
14.如何在頁面上實(shí)現(xiàn)一個(gè)圓形的可點(diǎn)擊區(qū)域?
map+area或者svg
border-radius
純js實(shí)現(xiàn) 需要求一個(gè)點(diǎn)在不在圓上簡單算法、獲取鼠標(biāo)坐標(biāo)等等
title屬性沒有明確意義只表示是個(gè)標(biāo)題,H1則表示層次明確的標(biāo)題,對(duì)頁面信息的抓取也有很大的影響;
strong是標(biāo)明重點(diǎn)內(nèi)容,有語氣加強(qiáng)的含義,使用閱讀設(shè)備閱讀網(wǎng)絡(luò)時(shí):會(huì)重讀,而是展示強(qiáng)調(diào)內(nèi)容。
i內(nèi)容展示為斜體,em表示強(qiáng)調(diào)的文本;
h5新增的屬性
可以通過ele.dataset獲取到標(biāo)簽上的data-x的屬性
返回一個(gè)對(duì)象
解決:解決方案是做成PNG8.
解決:方案是加一個(gè)全局的*{margin:0;padding:0;}來統(tǒng)一。
解決:解決方案是在float的標(biāo)簽樣式控制中加入 ——_display:inline;將其轉(zhuǎn)化為行內(nèi)屬性。(_這個(gè)符號(hào)只有ie6會(huì)識(shí)別)
漸進(jìn)識(shí)別的方式,從總體中逐漸排除局部。
首先,巧妙的使用“9”這一標(biāo)記,將IE游覽器從所有情況中分離出來。 接著,再次使用“+”將IE8和IE7、IE6分離開來,這樣IE8已經(jīng)獨(dú)立識(shí)別。
css
.bb{
background-color:#f1ee18;/*所有識(shí)別*/
.background-color:#00deff\9; /*IE6、7、8識(shí)別*/
+background-color:#a200ff;/*IE6、7識(shí)別*/
_background-color:#1e0bd1;/*IE6識(shí)別*/
}
解決:解決方法:統(tǒng)一通過getAttribute()獲取自定義屬性.
解決方法:(條件注釋)缺點(diǎn)是在IE瀏覽器下可能會(huì)增加額外的HTTP請(qǐng)求數(shù)。
解決:可通過加入 CSS 屬性 -webkit-text-size-adjust: none; 解決.
解決:方法是改變CSS屬性的排列順序:L-V-H-A : a:link {} a:visited {} a:hover {} a:active {}
該標(biāo)簽可聲明三種 DTD 類型,分別表示嚴(yán)格版本、過渡版本以及基于框架的 HTML 文檔。
HTML 4.01 規(guī)定了三種文檔類型:Strict、Transitional 以及 Frameset。
XHTML 1.0 規(guī)定了三種 XML 文檔類型:Strict、Transitional 以及 Frameset。
Standards (標(biāo)準(zhǔn))模式(也就是嚴(yán)格呈現(xiàn)模式)用于呈現(xiàn)遵循最新標(biāo)準(zhǔn)的網(wǎng)頁,而 Quirks(包容)模式(也就是松散呈現(xiàn)模式或者兼容模式)用于呈現(xiàn)為傳統(tǒng)瀏覽器而設(shè)計(jì)的網(wǎng)頁。
1)所有的標(biāo)記都必須要有一個(gè)相應(yīng)的結(jié)束標(biāo)記
2)所有標(biāo)簽的元素和屬性的名字都必須使用小寫
3)所有的XML標(biāo)記都必須合理嵌套
4)所有的屬性必須用引號(hào)""括起來
5)把所有<和&特殊符號(hào)用編碼表示
6)給所有屬性賦一個(gè)值
7)不要在注釋內(nèi)容中使“--”
8)圖片必須有說明文字
title是global attributes之一,用于為元素提供附加的advisory information。通常當(dāng)鼠標(biāo)滑動(dòng)到元素上的時(shí)候顯示。
alt是<img>的特有屬性,是圖片內(nèi)容的等價(jià)描述,用于圖片無法加載時(shí)顯示、讀屏器閱讀圖片。可提圖片高可訪問性,除了純裝飾圖片外都必須設(shè)置有意義的值,搜索引擎會(huì)重點(diǎn)分析。
改版的時(shí)候更方便 只要改css文件。
頁面加載速度更快、結(jié)構(gòu)化清晰、頁面顯示簡潔。
表現(xiàn)與結(jié)構(gòu)相分離。
易于優(yōu)化(seo)搜索引擎更友好,排名更容易靠前。
派生選擇器(用HTML標(biāo)簽申明)
id選擇器(用DOM的ID申明)
類選擇器(用一個(gè)樣式類名申明)
屬性選擇器(用DOM的屬性申明,屬于CSS2,IE6不支持,不常用,不知道就算了)
除了前3種基本選擇器,還有一些擴(kuò)展選擇器,包括
后代選擇器(利用空格間隔,比如div .a{ })
群組選擇器(利用逗號(hào)間隔,比如p,div,#a{ })
那么問題來了,CSS選擇器的優(yōu)先級(jí)是怎么樣定義的?
一般而言,選擇器越特殊,它的優(yōu)先級(jí)越高。也就是選擇器指向的越準(zhǔn)確,它的優(yōu)先級(jí)就越高。
復(fù)雜的計(jì)算方法:
用1表示派生選擇器的優(yōu)先級(jí)
用10表示類選擇器的優(yōu)先級(jí)
用100標(biāo)示ID選擇器的優(yōu)先級(jí)
div.test1 .span var 優(yōu)先級(jí) 1+10 +10 +1
span#xxx .songs li 優(yōu)先級(jí)1+100 + 10 + 1
xxx li 優(yōu)先級(jí) 100 +1
那么問題來了,看下列代碼,<p>標(biāo)簽內(nèi)的文字是什么顏色的?
<style>
.classA{ color:blue;}
.classB{ color:red;}
</style>
<body>
<p class='classB classA'> 123 </p>
</body>
答案:red。與樣式定義在文件中的先后順序有關(guān),即是后面的覆蓋前面的,與在<p class=’classB classA’>中的先后關(guān)系無關(guān)。
塊級(jí)元素(block)特性:
總是獨(dú)占一行,表現(xiàn)為另起一行開始,而且其后的元素也必須另起一行顯示;
寬度(width)、高度(height)、內(nèi)邊距(padding)和外邊距(margin)都可控制;
內(nèi)聯(lián)元素(inline)特性:
和相鄰的內(nèi)聯(lián)元素在同一行;
寬度(width)、高度(height)、內(nèi)邊距的top/bottom(padding-top/padding-bottom)和外邊距的top/bottom(margin-top/margin-bottom)都不可改變(也就是padding和margin的left和right是可以設(shè)置的),就是里面文字或圖片的大小。
那么問題來了,瀏覽器還有默認(rèn)的天生inline-block元素(擁有內(nèi)在尺寸,可設(shè)置高寬,但不會(huì)自動(dòng)換行),有哪些?
答案:<input> 、<img> 、<button> 、<texterea> 、<label>。
外邊距重疊就是margin-collapse。
在CSS當(dāng)中,相鄰的兩個(gè)盒子(可能是兄弟關(guān)系也可能是祖先關(guān)系)的外邊距可以結(jié)合成一個(gè)單獨(dú)的外邊距。這種合并外邊距的方式被稱為折疊,并且因而所結(jié)合成的外邊距稱為折疊外邊距。
折疊結(jié)果遵循下列計(jì)算規(guī)則:
兩個(gè)相鄰的外邊距都是正數(shù)時(shí),折疊結(jié)果是它們兩者之間較大的值。
兩個(gè)相鄰的外邊距都是負(fù)數(shù)時(shí),折疊結(jié)果是兩者絕對(duì)值的較大值。
兩個(gè)外邊距一正一負(fù)時(shí),折疊結(jié)果是兩者的相加的和。
rgba()和opacity都能實(shí)現(xiàn)透明效果,但最大的不同是opacity作用于元素,以及元素內(nèi)的所有內(nèi)容的透明度,
而rgba()只作用于元素的顏色或其背景色。(設(shè)置rgba透明的元素的子元素不會(huì)繼承透明效果!)
* 1.id選擇器( # myid)
2.類選擇器(.myclassname)
3.標(biāo)簽選擇器(div, h1, p)
4.相鄰選擇器(h1 + p)
5.子選擇器(ul < li)
6.后代選擇器(li a)
7.通配符選擇器( * )
8.屬性選擇器(a[rel="external"])
9.偽類選擇器(a: hover, li: nth - child)
* 可繼承: font-size font-family color, UL LI DL DD DT;
* 不可繼承 :border padding margin width height ;
* 優(yōu)先級(jí)就近原則,樣式定義最近者為準(zhǔn);
* 載入樣式以最后載入的定位為準(zhǔn);
優(yōu)先級(jí)為:
!important > id > class > tag
important 比 內(nèi)聯(lián)優(yōu)先級(jí)高
CSS3新增偽類舉例:
p:first-of-type 選擇屬于其父元素的首個(gè) <p> 元素的每個(gè) <p> 元素。
p:last-of-type 選擇屬于其父元素的最后 <p> 元素的每個(gè) <p> 元素。
p:only-of-type 選擇屬于其父元素唯一的 <p> 元素的每個(gè) <p> 元素。
p:only-child 選擇屬于其父元素的唯一子元素的每個(gè) <p> 元素。
p:nth-child(2) 選擇屬于其父元素的第二個(gè)子元素的每個(gè) <p> 元素。
:enabled、:disabled 控制表單控件的禁用狀態(tài)。
:checked,單選框或復(fù)選框被選中。
給div設(shè)置一個(gè)寬度,然后添加margin:0 auto屬性
div{
width:200px;
margin:0 auto;
}
居中一個(gè)浮動(dòng)元素
確定容器的寬高 寬500 高 300 的層
設(shè)置層的外邊距
.div {
Width:500px ; height:300px;//高度可以不設(shè)
Margin: -150px 0 0 -250px;
position:relative;相對(duì)定位
background-color:pink;//方便看效果
left:50%;
top:50%;
}
* IE瀏覽器的內(nèi)核Trident、 Mozilla的Gecko、google的WebKit、Opera內(nèi)核Presto;
* png24為的圖片在iE6瀏覽器上出現(xiàn)背景,解決方案是做成PNG8.
* 瀏覽器默認(rèn)的margin和padding不同。解決方案是加一個(gè)全局的*{margin:0;padding:0;}來統(tǒng)一。
* IE6雙邊距bug:塊屬性標(biāo)簽float后,又有橫行的margin情況下,在ie6顯示margin比設(shè)置的大。
浮動(dòng)ie產(chǎn)生的雙倍距離 #box{ float:left; width:10px; margin:0 0 0 100px;}
這種情況之下IE會(huì)產(chǎn)生20px的距離,解決方案是在float的標(biāo)簽樣式控制中加入 ——_display:inline;將其轉(zhuǎn)化為行內(nèi)屬性。(_這個(gè)符號(hào)只有ie6會(huì)識(shí)別)
漸進(jìn)識(shí)別的方式,從總體中逐漸排除局部。
首先,巧妙的使用“\9”這一標(biāo)記,將IE游覽器從所有情況中分離出來。
接著,再次使用“+”將IE8和IE7、IE6分離開來,這樣IE8已經(jīng)獨(dú)立識(shí)別。
css
.bb{
background-color:#f1ee18;/*所有識(shí)別*/
.background-color:#00deff\9; /*IE6、7、8識(shí)別*/
+background-color:#a200ff;/*IE6、7識(shí)別*/
_background-color:#1e0bd1;/*IE6識(shí)別*/
}
* IE下,可以使用獲取常規(guī)屬性的方法來獲取自定義屬性,
也可以使用getAttribute()獲取自定義屬性;
Firefox下,只能使用getAttribute()獲取自定義屬性.
解決方法:統(tǒng)一通過getAttribute()獲取自定義屬性.
* IE下,even對(duì)象有x,y屬性,但是沒有pageX,pageY屬性;
Firefox下,event對(duì)象有pageX,pageY屬性,但是沒有x,y屬性.
* (條件注釋)缺點(diǎn)是在IE瀏覽器下可能會(huì)增加額外的HTTP請(qǐng)求數(shù)。
* Chrome 中文界面下默認(rèn)會(huì)將小于 12px 的文本強(qiáng)制按照 12px 顯示, 可通過加入 CSS 屬性 -webkit-text-size-adjust: none; 解決.
超鏈接訪問過后hover樣式就不出現(xiàn)了 被點(diǎn)擊訪問過的超鏈接樣式不在具有hover和active了解決方法是改變CSS屬性的排列順序:
L-V-H-A : a:link {} a:visited {} a:hover {} a:active {}
!important > id > class > 標(biāo)簽
!important 比 內(nèi)聯(lián)優(yōu)先級(jí)高
可繼承: font-size font-family color, ul li dl dd dt;
不可繼承 :border padding margin width height ;
講 DOM 先從 HTML 講起,講 HTML 先從 XML 講起。XML 是一種可擴(kuò)展的標(biāo)記語言,所謂可擴(kuò)展就是它可以描述任何結(jié)構(gòu)化的數(shù)據(jù),它是一棵樹!
document.write只能重繪整個(gè)頁面
innerHTML可以重繪頁面的一部分
createDocumentFragment() //創(chuàng)建一個(gè)DOM片段
createElement() //創(chuàng)建一個(gè)具體的元素
createTextNode() //創(chuàng)建一個(gè)文本節(jié)點(diǎn)
appendChild()
removeChild()
replaceChild()
insertBefore() //在已有的子節(jié)點(diǎn)前插入一個(gè)新的子節(jié)點(diǎn)
getElementsByTagName() //通過標(biāo)簽名稱
getElementsByName() //通過元素的Name屬性的值(IE容錯(cuò)能力較強(qiáng),會(huì)得到一個(gè)數(shù)組,其中包括id等于name值的)
getElementById() //通過元素Id,唯一性
attribute是dom元素在文檔中作為html標(biāo)簽擁有的屬性;
property就是dom元素在js中作為對(duì)象擁有的屬性。
所以:
對(duì)于html的標(biāo)準(zhǔn)屬性來說,attribute和property是同步的,是會(huì)自動(dòng)更新的,
但是對(duì)于自定義的屬性來說,他們是不同步的,
src用于替換當(dāng)前元素,href用于在當(dāng)前文檔和引用資源之間確立聯(lián)系。
src是source的縮寫,指向外部資源的位置,指向的內(nèi)容將會(huì)嵌入到文檔中當(dāng)前標(biāo)簽所在位置;在請(qǐng)求src資源時(shí)會(huì)將其指向的資源下載并應(yīng)用到文檔內(nèi),當(dāng)瀏覽器解析到該元素時(shí),會(huì)暫停其他資源的下載和處理,直到將該資源加載、編譯、執(zhí)行完畢,圖片和框架等元素也如此,類似于將所指向資源嵌入當(dāng)前標(biāo)簽內(nèi)。這也是為什么將js腳本放在底部而不是頭部。
Src source,指向外部資源的位置,如果我們添加<script src="js.js"></script>瀏覽器會(huì)暫停其他資源的下載和處理,直到該資源加載,編譯,執(zhí)行完畢(圖片和框架也是如此),這也就是為什么js腳本要放在底部。
src用于替換當(dāng)前元素,href用于在當(dāng)前文檔和引入資源之間建立聯(lián)系。
cookie 本身不是用來做服務(wù)器端存儲(chǔ)的(計(jì)算機(jī)領(lǐng)域有很多這種“狗拿耗子”的例子,例如 CSS 中的 float),它是設(shè)計(jì)用來在服務(wù)器和客戶端進(jìn)行信息傳遞的,因此我們的每個(gè) HTTP 請(qǐng)求都帶著 cookie。但是 cookie 也具備瀏覽器端存儲(chǔ)的能力(例如記住用戶名和密碼),因此就被開發(fā)者用上了。
使用起來也非常簡單,document.cookie=....即可。
但是 cookie 有它致命的缺點(diǎn):
存儲(chǔ)量太小,只有 4KB
所有 HTTP 請(qǐng)求都帶著,會(huì)影響獲取資源的效率
API 簡單,需要封裝才能用
后來,HTML5 標(biāo)準(zhǔn)就帶來了sessionStorage和localStorage,先拿localStorage來說,它是專門為了瀏覽器端緩存而設(shè)計(jì)的。
存儲(chǔ)量增大到 5MB
不會(huì)帶到 HTTP 請(qǐng)求中
API 適用于數(shù)據(jù)存儲(chǔ) localStorage.setItem(key, value) localStorage.getItem(key)
sessionStorage的區(qū)別就在于它是根據(jù) session 過去時(shí)間而實(shí)現(xiàn),而localStorage會(huì)永久有效,應(yīng)用場(chǎng)景不同。例如,一些需要及時(shí)失效的重要信息放在sessionStorage中,一些不重要但是不經(jīng)常設(shè)置的信息,放在localStorage中。
標(biāo)簽閉合、標(biāo)簽小寫、不亂嵌套、提高搜索機(jī)器人搜索幾率、使用外 鏈css和js腳本、結(jié)構(gòu)行為表現(xiàn)的分離、文件下載與頁面速度更快、內(nèi)容能被更多的用戶所訪問、內(nèi)容能被更廣泛的設(shè)備所訪問、更少的代碼和組件,容易維 護(hù)、改版方便,不需要變動(dòng)頁面內(nèi)容、提供打印版本而不需要復(fù)制內(nèi)容、提高網(wǎng)站易用性;
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。