成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Js知識(shí)點(diǎn)集錦

GeekGhc / 3921人閱讀

摘要:形如字符串中的將會(huì)被替換掉。根據(jù)給定正則表達(dá)式的匹配拆分此字符串。表示沒(méi)有對(duì)象,即該處不應(yīng)該有值。需要說(shuō)明一點(diǎn)的是變量沒(méi)有使用顯示聲明,但是在使用前已經(jīng)賦值,這個(gè)值是被隱性聲明未全局變量。否則存入結(jié)果數(shù)組。對(duì)象保存鍵值對(duì)。

1、String類的常用方法

length():求字符串的長(zhǎng)度
indexOf():求某個(gè)字符在字符串中的位置
charAt():求一個(gè)字符串中某個(gè)位置的值
equals():比較兩個(gè)字符串是否相同
replace():將字符串中的某些字符用別的字符替換掉。形如replace(“abc”,”ffffd”);字符串中的abc將會(huì)被ffffd替換掉。
split():根據(jù)給定正則表達(dá)式的匹配拆分此字符串。形如 String s = "The time is going quickly!"; str1=s.split(" ");
substring():輸出一個(gè)新的字符串,它是此字符串中的子串,形如substring(3,7);它將字符串中的第四個(gè)第五個(gè)第六個(gè)輸出。
trim():將字符串開頭的空白(空格)和尾部的空白去掉。
format():使用指定的語(yǔ)言環(huán)境、格式字符串和參數(shù)返回一個(gè)格式化字符串。
toLowerCase():將字符串中所有的大寫改變成小寫
toUpperCase():將字符串中所有的小寫改變?yōu)榇髮?/pre>

https://cloud.tencent.com/dev...
https://www.cnblogs.com/YYvam...
2、數(shù)組的常用方法

Push()尾部添加
pop()尾部刪除
Unshift()頭部添加
shift()頭部刪除


https://www.cnblogs.com/rongy...
https://blog.csdn.net/qq_3913...
https://www.jianshu.com/p/e1b...
https://www.cnblogs.com/songz...
3、JavaScript 數(shù)據(jù)類型

值類型(基本類型):字符串(String)、數(shù)字(Number)、布爾(Boolean)、對(duì)空(Null)、未定義(Undefined)、Symbol。

undefined與null的區(qū)別: http://www.ruanyifeng.com/blo...

null是一個(gè)表示"無(wú)"的對(duì)象,轉(zhuǎn)為數(shù)值時(shí)為0;undefined是一個(gè)表示"無(wú)"的原始值,轉(zhuǎn)為數(shù)值時(shí)為NaN。
Number(undefined)
NaN

Number(null)
0
null表示"沒(méi)有對(duì)象",即該處不應(yīng)該有值。
undefined表示"缺少值",就是此處應(yīng)該有一個(gè)值,但是還沒(méi)有定義。

(1)變量被聲明了,但沒(méi)有賦值時(shí),就等于undefined。

(2) 調(diào)用函數(shù)時(shí),應(yīng)該提供的參數(shù)沒(méi)有提供,該參數(shù)等于undefined。

(3)對(duì)象沒(méi)有賦值的屬性,該屬性的值為undefined。

(4)函數(shù)沒(méi)有返回值時(shí),默認(rèn)返回undefined。

var i;
i // undefined

function f(x){console.log(x)}
f() // undefined

var  o = new Object();
o.p // undefined

var x = f();
x // undefined

Undefine變量和undeclared變量分別指什么

undefined是Javascript中的語(yǔ)言類型之一,而undeclared是Javascript中的一種語(yǔ)法錯(cuò)誤。
undefined的是聲明了但是沒(méi)有賦值,javascript在使用該變量是不會(huì)報(bào)錯(cuò)。
var a=undefined; 
var b;

undeclared 是未聲明也未賦值的變量,JavaScript訪問(wèn)會(huì)報(bào)錯(cuò)。

a;
b=10;

需要說(shuō)明一點(diǎn)的是變量沒(méi)有使用var 顯示聲明,但是在使用前已經(jīng)賦值,這個(gè)值是被隱性聲明未全局變量。
https://www.jianshu.com/p/67f...
https://www.jianshu.com/p/3ad...
引用數(shù)據(jù)類型:對(duì)象(Object)、數(shù)組(Array)、函數(shù)(Function)。
:Symbol 是 ES6 引入了一種新的原始數(shù)據(jù)類型,表示獨(dú)一無(wú)二的值,可以保證不會(huì)與其他屬性名產(chǎn)生沖突。

Symbol(js的第七種數(shù)據(jù)類型):https://www.cnblogs.com/sunsh...
https://segmentfault.com/a/11...

javascript的typeof返回哪些數(shù)據(jù)類型

1)返回?cái)?shù)據(jù)類型

  undefined,string,boolean,number,symbol(ES6),Object,F(xiàn)unction

2)強(qiáng)制類型轉(zhuǎn)換

Number(參數(shù))把任何類型轉(zhuǎn)換成數(shù)值類型
parseInt(參數(shù)1,參數(shù)2)將字符串轉(zhuǎn)換成整數(shù)
parseFloat()將字符串轉(zhuǎn)換成浮點(diǎn)數(shù)字
string(參數(shù)):可以將任何類型轉(zhuǎn)換成字符串
Boolean()可以將任何類型的值轉(zhuǎn)換成布爾值

3)隱式類型轉(zhuǎn)換
+,-,== , ===

4、js事件

事件類型有:
UI(用戶界面)事件:用戶與頁(yè)面上元素交互時(shí)觸發(fā) ;
焦點(diǎn)事件:當(dāng)元素獲得或失去焦點(diǎn)時(shí)觸發(fā) ;
文本事件:當(dāng)在文檔中輸入文本時(shí)觸發(fā);
鍵盤事件:當(dāng)用戶通過(guò)鍵盤在頁(yè)面上執(zhí)行操作時(shí)觸發(fā);
鼠標(biāo)事件:當(dāng)用戶通過(guò)鼠標(biāo)在頁(yè)面上執(zhí)行操作時(shí)觸發(fā);
滾輪事件:當(dāng)使用鼠標(biāo)滾輪(或類似設(shè)備)時(shí)觸發(fā)。

它們之間是繼承的關(guān)系,如下圖:

https://www.cnblogs.com/jingw...

5、JS實(shí)現(xiàn)數(shù)組去重

1、遍歷數(shù)組法:新建一個(gè)數(shù)組,遍歷去要重的數(shù)組,當(dāng)值不在新數(shù)組的時(shí)候(indexOf為-1)就加入該新數(shù)組中。
將整個(gè)數(shù)組遍歷一遍,如果之前沒(méi)有出現(xiàn)過(guò),將其放到一個(gè)新的數(shù)組中,最后返回這個(gè)數(shù)組。
var arr=[2,8,5,0,5,2,6,7,2];
function unique1(arr){
  var hash=[];
  for (var i = 0; i < arr.length; i++) {
     if(hash.indexOf(arr[i])==-1){
      hash.push(arr[i]);
     }
  }
  return hash;
}
var arr1 =[1,2,2,2,3,3,3,4,5,6],
    arr2 = []; //一個(gè)新的臨時(shí)數(shù)組
for(var i = 0,len = arr1.length; i< len; i++){
        //如果當(dāng)前數(shù)組的第i已經(jīng)保存進(jìn)了臨時(shí)數(shù)組,那么跳過(guò),
        //否則把當(dāng)前項(xiàng)push到臨時(shí)數(shù)組里面
    if(arr2.indexOf(arr1[i]) < 0){
        arr2.push(arr1[i]);
    }
}
document.write(arr2); // 1,2,3,4,5,6
2、數(shù)組下標(biāo)判斷法:如果當(dāng)前數(shù)組的第 i 項(xiàng)在當(dāng)前數(shù)組中第一次出現(xiàn)的位置不是 i,那么表示第 i 項(xiàng)是重復(fù)的,忽略掉。否則存入結(jié)果數(shù)組。
比如2第一次出現(xiàn)時(shí),下標(biāo)是0,第二次出現(xiàn)時(shí),下標(biāo)卻是4,表示有重復(fù)的2
function unique2(arr){
  var hash=[];
  for (var i = 0; i < arr.length; i++) {
     if(arr.indexOf(arr[i])==i){
      hash.push(arr[i]);
     }
  }
  return hash;
}
3、排序后相鄰去除法 :給傳入的數(shù)組排序,排序后相同的值會(huì)相鄰,然后遍歷排序后數(shù)組時(shí),新數(shù)組只加入不與前一值重復(fù)的值
var arr=[2,8,5,0,5,2,6,7,2];
function unique3(arr){
  arr.sort();
  var hash=[arr[0]];
  for (var i = 1; i < arr.length; i++) {
     if(arr[i]!=hash[hash.length-1]){
      hash.push(arr[i]);
     }
  }
  return hash;
}
console.log(unique3(arr))//?[0, 2, 5, 6, 7, 8]

4、ES6提供了新的數(shù)據(jù)結(jié)構(gòu)Set。它類似于數(shù)組,但是成員的值都是唯一的,沒(méi)有重復(fù)的值。
var arr=[2,8,5,0,5,2,6,7,2];
function unique5(arr){
  var x = new Set(arr);
  return x;
}
console.log(unique5(arr)) //Set(6)?{2, 8, 5, 0, 6,7}
let array = Array.from(unique5(arr));
console.log(array);//[2,8,5,0,6,7]
var arr=[2,8,5,0,5,2,6,7,2];
function unique(arr) {
  return Array.from(new Set(arr))
}
console.log(unique(arr))//[2,8,5,0,6,7]
Map是ES6 提供的新的數(shù)據(jù)結(jié)構(gòu)。
Map 對(duì)象保存鍵值對(duì)。任何值(對(duì)象或者原始值) 都可以作為一個(gè)鍵或一個(gè)值。
filter() 方法創(chuàng)建一個(gè)新的數(shù)組,新數(shù)組中的元素 是 通過(guò)檢查 指定數(shù)組 中 符合條件的所有元素。
var arr=[2,8,5,0,5,2,6,7,2];
function unique(arr) {
  //定義常量 res,值為一個(gè)Map對(duì)象實(shí)例
  const res = new Map();
  //返回arr數(shù)組過(guò)濾后的結(jié)果,結(jié)果為一個(gè)數(shù)組
  //過(guò)濾條件是,如果res中沒(méi)有某個(gè)鍵,就設(shè)置這個(gè)鍵的值為1
  return arr.filter((a) => !res.has(a) && res.set(a, 1))
}
console.log(unique(arr))//[2,8,5,0,6,7]


https://www.cnblogs.com/jiayu...
https://blog.csdn.net/fe_dev/...

數(shù)組的from方法--Array.from()
數(shù)組的from方法可以把一個(gè)類數(shù)組(偽數(shù)組)或者可遍歷(可循環(huán))的對(duì)象轉(zhuǎn)化成一個(gè)真正的數(shù)組,例如
const bar = ["a", "b", "c"];
Array.from(bar);
// ["a", "b", "c"]

Array.from("foo");
// ["f", "o", "o"]
var a = {
    0: "a",
    1: "90",
    2: "88",
    3: ["mm", "nn", "hh"],
    "length": 4 // 不帶引號(hào)直接 length: 4 也是行的
}
var b = Array.from(a);
console.log(b) // ["a","90","88",["mm","nn","hh"]]
function unique(arr) {
    //通過(guò)Set對(duì)象,對(duì)數(shù)組去重,結(jié)果又返回一個(gè)Set對(duì)象
    //通過(guò)from方法,將Set對(duì)象轉(zhuǎn)為數(shù)組
    return Array.from(new Set(arr))
}
ES6去重:
http://blog.csdn.net/FE_dev/a...
https://my.oschina.net/u/3946...

6、js 防止連續(xù)點(diǎn)擊登錄驗(yàn)證碼
https://www.cnblogs.com/yangs...
7、如何用JS有效防止用戶重復(fù)點(diǎn)擊提交按鈕?
https://segmentfault.com/q/10...
https://blog.csdn.net/iosbird...
8、Input框防抖動(dòng)
https://segmentfault.com/a/11...
9、如何壓縮css,js

性能一直是項(xiàng)目中比較重要的一點(diǎn),尤其門戶網(wǎng)站,對(duì)頁(yè)面的響應(yīng)要求是很高的,從性能角度上來(lái)講,對(duì)于Web端的優(yōu)化其中重要的一點(diǎn)無(wú)疑是JS、CSS文件壓縮,圖片的融合,盡量減小文件的大小,必免占加載時(shí)占用過(guò)多的帶寬。yui compressor無(wú)疑是一個(gè)比較好的壓縮工具,是yahoo的一個(gè)開源組件.

https://www.cnblogs.com/cbing...
https://blog.csdn.net/weixin_...

10、ES6 數(shù)組some()和every()使用:

用于檢測(cè)數(shù)組中的元素是否滿足指定條件(函數(shù)提供)

every:一假即假:
some:一真即真

some()方法 只要其中一個(gè)為true 就會(huì)返回true;
every()方法必須所有都返回true才會(huì)返回true,哪怕有一個(gè)false,就會(huì)返回false;
every()和 some()目的:確定數(shù)組的所有成員是否滿足指定的測(cè)試。
var ages = [23,44,3]
if (ages.some(age => age < 10)) {
//console.log("true")
}
/** 
 * 計(jì)算對(duì)象數(shù)組中每個(gè)電腦的扣件系統(tǒng)是否可用,大于16位操作系統(tǒng)表示可用,否則不可用
*/
var computers = [
    {name:"Apple",ram:8},
    {name:"IBM",ram:4},
    {name:"Acer",ram:32},
];
 var result= computers.every(function(computer){
   return computer.ram > 16
})
console.log(result)//false;
var some = computers.some(function(computer){
   return computer.ram > 16
})
console.log(some)//true;
/**
 * 假定有一個(gè)注冊(cè)頁(yè)面,判斷所有Input內(nèi)容的長(zhǎng)度是否大于0
 * 
 */
function Field(value){
    this.value = value
}
// 在原型上定義方法
Field.prototype.validate = function(){
    return this.value.length > 0;
}
var username = new Field("2131");
var telephone  = new Field("8888888888888")
console.log(username.validate() && telephone.validate())//true
 
 
//二`:
var username = new Field("2131");
var telephone  = new Field("8888888888888")
let password  = new Field("");
//console.log(username.validate() && telephone.validate())//只要一個(gè)為空就為false
// 簡(jiǎn)化方式
var fields = [username, telephone,password];
console.log(fields)
var formIsValid = fields.every(function(field){
    return field.validate()
});
console.log(formIsValid)
 
if(formIsValid){
    //注冊(cè)成功
}else{
    //給用戶一個(gè)錯(cuò)誤提醒
}

11、es6中import、export和export default的作用、區(qū)別

作用:export和export default實(shí)現(xiàn)的功能相同,即:可用于導(dǎo)出(暴露)常量、函數(shù)、文件、模塊等,以便其他文件調(diào)用。

區(qū)別:

export導(dǎo)出多個(gè)對(duì)象,export default只能導(dǎo)出一個(gè)對(duì)象

export導(dǎo)出對(duì)象需要用{ },export default不需要{ },使用export default命令,為模塊指定默認(rèn)輸出,這樣就不需要知道所要加載模塊的變量名。

如:

export {A,B,C};
export default A;

在其他文件引用export default導(dǎo)出的對(duì)象時(shí)不一定使用導(dǎo)出時(shí)的名字。因?yàn)檫@種方式實(shí)際上是將該導(dǎo)出對(duì)象設(shè)置為默認(rèn)導(dǎo)出對(duì)象,如:
假設(shè)文件A、B在同級(jí)目錄,實(shí)現(xiàn)文件B引入文件A的導(dǎo)出對(duì)象deObject:

文件A:export default deObject
文件B:import deObject from "./A"
       或者:
    import newDeObject from "./A"
export和import(一個(gè)導(dǎo)出一個(gè)導(dǎo)入)
export用于對(duì)外輸出本模塊(一個(gè)文件可以理解為一個(gè)模塊)變量的接口
import用于在一個(gè)模塊中加載另一個(gè)含有export接口的模塊。
也就是說(shuō)使用export命令定義了模塊的對(duì)外接口以后,其他JS文件就可以通過(guò)import命令加載這個(gè)模塊(文件)。這幾個(gè)都是ES6的語(yǔ)法。
var name1="李四";
 var name2="張三";
 export { name1 ,name2 }
import { name1 , name2 } from "/.a.js" //路徑根據(jù)你的實(shí)際情況填寫
export default {
  data () {
    return { }
  },
  created:function(){
    alert(name1)//可以彈出來(lái)“李四”
    alert(name2)//可以彈出來(lái)“張三”
  }
 }

https://www.cnblogs.com/xiaot...
12、call和applay

它們各自的定義:

apply:應(yīng)用某一對(duì)象的一個(gè)方法,用另一個(gè)對(duì)象替換當(dāng)前對(duì)象。例如:B.apply(A, arguments);即A對(duì)象應(yīng)用B對(duì)象的方法。
call:調(diào)用一個(gè)對(duì)象的一個(gè)方法,以另一個(gè)對(duì)象替換當(dāng)前對(duì)象。例如:B.call(A, args1,args2);即A對(duì)象調(diào)用B對(duì)象的方法。

它們的共同之處:

都可以用來(lái)代替另一個(gè)對(duì)象調(diào)用一個(gè)方法,將一個(gè)函數(shù)的對(duì)象上下文從初始的上下文改變?yōu)橛蓆hisObj指定的新對(duì)象。

它們的不同之處:

call:call方法從第二個(gè)參數(shù)開始可以接收任意個(gè)參數(shù),每個(gè)參數(shù)會(huì)映射到相應(yīng)位置的func的參數(shù)上,可以通過(guò)參數(shù)名調(diào)用,但是如果將所有的參數(shù)作為數(shù)組傳入,它們會(huì)作為一個(gè)整體映射到func對(duì)應(yīng)的第一個(gè)參數(shù)上,之后參數(shù)都為空.
function func (a,b,c) {}

func.call(obj, 1,2,3)
// function接收到的參數(shù)實(shí)際上是 1,2,3

func.call(obj, [1,2,3])
// function接收到的參數(shù)實(shí)際上是 [1,2,3],undefined,undefined
apply:apply方法最多只有兩個(gè)參數(shù),第二個(gè)參數(shù)接收數(shù)組或者類數(shù)組,但是都會(huì)被轉(zhuǎn)換成類數(shù)組傳入func中,并且會(huì)被映射到func對(duì)應(yīng)的參數(shù)上.
func.apply(obj, [1,2,3])
// function接收到的參數(shù)實(shí)際上是 1,2,3

func.apply(obj, {
    0: 1,
    1: 2,
    2: 3,
    length: 3
})
// function接收到的參數(shù)實(shí)際上是 1,2,3

實(shí)際上,apply和call的功能是一樣的,只是傳入的參數(shù)列表形式不同。

Object.call(this,obj1,obj2,obj3)
Object.apply(this,arguments)
function add(a,b){
  return a+b;  
}
function sub(a,b){
  return a-b;  
}

/*apply的用法*/
var a1 = add.apply(sub,[4,2]);  //sub調(diào)用add的方法
var a2 = sub.apply(add,[4,2]);
alert(a1);  //6     
alert(a2);  //2

/*call的用法*/
var a1 = add.call(sub,4,2); //6
Array.prototype.push可以實(shí)現(xiàn)兩個(gè)數(shù)組的合并
同樣push方法沒(méi)有提供push一個(gè)數(shù)組,但是它提供了push(param1,param2...paramN),同樣也可以用apply來(lái)轉(zhuǎn)換一下這個(gè)數(shù)組,即:
var arr1=new Array("1","2","3");
var arr2=new Array("4","5","6");
Array.prototype.push.apply(arr1,arr2);    //6  得到合并后數(shù)組的長(zhǎng)度,因?yàn)閜ush就是返回一個(gè)數(shù)組的長(zhǎng)度
怎么讓類數(shù)組使用forEach?   讓類數(shù)組綁定數(shù)組的方法
1
2

方法1:

let div = document.getElementsByTagName("div");
 
div.forEach = Array.prototype.forEach;
 
div.forEach(item=>{
    console.log(item);
});

方法2:

[].forEach.call(document.getElementsByTagName("div"), (item) => console.log(item))

方法3:

[].forEach.apply(document.getElementsByTagName("div"), [(item) => console.log(item)])

方法4:

var getDivs = [].forEach.bind(document.getElementsByTagName("div"))
getDivs(item => console.log(item))

方法5:

document.querySelectorAll("div").forEach(item => console.log(item))
bind()方法,他是直接改變這個(gè)函數(shù)的this指向并且返回一個(gè)新的函數(shù),之后再次調(diào)用這個(gè)函數(shù)的時(shí)候this都是指向bind綁定的第一個(gè)參數(shù)。bind傳餐方式跟call方法一致。
// 如果你想將某個(gè)函數(shù)綁定新的`this`指向并且固定先傳入幾個(gè)變量可以在綁定的時(shí)候就傳入,之后調(diào)用新函數(shù)傳入的參數(shù)都會(huì)排在之后
const obj = {}
function test(...args) {console.log(args)}
const newFn = test.bind(obj, "靜態(tài)參數(shù)1", "靜態(tài)參數(shù)2")
newFn("動(dòng)態(tài)參數(shù)3", "動(dòng)態(tài)參數(shù)4")

總結(jié)

當(dāng)我們使用一個(gè)函數(shù)需要改變this指向的時(shí)候才會(huì)用到call、 apply、 bind

如果你要傳遞的參數(shù)不多,則可以使用fn.call(thisObj, arg1, arg2 ...)

如果你要傳遞的參數(shù)很多,則可以用數(shù)組將參數(shù)整理好調(diào)用fn.apply(thisObj, [arg1, arg2 ...])

如果你想生成一個(gè)新的函數(shù)長(zhǎng)期綁定某個(gè)函數(shù)給某個(gè)對(duì)象使用,則可以使用const newFn = fn.bind(thisObj); newFn(arg1, arg2...)

https://www.jianshu.com/p/131...
https://www.jianshu.com/p/bc5...
13、作用域

作用域:即某些變量的適用范圍
function fun(){} ;// 這是指函數(shù)變量. 函數(shù)變量一般也說(shuō)成函數(shù)聲明。
ar getA=function fun(){}; //這也是函數(shù)表達(dá)式

聲明是在函數(shù)第一行代碼執(zhí)行之前就已經(jīng)完成,而賦值是在函數(shù)執(zhí)行時(shí)期才開始賦值。所以,聲明總是存在于賦值之前。

https://www.cnblogs.com/wupei...
作用域鏈:https://www.cnblogs.com/renlo...
javascript變量提升:https://www.cnblogs.com/ghost...

14、prototype
https://segmentfault.com/a/11...

一、什么是原型(prototype)
1、prototype本質(zhì)上還是一個(gè)JavaScript對(duì)象;

2、每個(gè)函數(shù)都有一個(gè)默認(rèn)的prototype屬性;

3、通過(guò)prototype我們可以擴(kuò)展Javascript的內(nèi)建對(duì)象
二. 原型鏈:

常用原型來(lái)實(shí)現(xiàn)繼承,其基本思想是利用原型讓一個(gè)引用類型繼承另一個(gè)引用類型的屬性和方法。簡(jiǎn)單說(shuō),構(gòu)造函數(shù)、原型和實(shí)例的關(guān)系:每個(gè)構(gòu)造函數(shù)都有一個(gè)原型對(duì)象,原型對(duì)象都包含一個(gè)指向構(gòu)造函數(shù)的指針,而實(shí)例都包含一個(gè)指向原型對(duì)象的內(nèi)部指針。假如我們讓原型對(duì)象等于另一個(gè)類型的實(shí)例。那結(jié)果將是:此時(shí)的原型對(duì)象將包含一個(gè)指向另一個(gè)原型的指針,相應(yīng)地,另一個(gè)原型中也包含著一個(gè)指向另一個(gè)構(gòu)造函數(shù)的指針。假如另一個(gè)原型又是另一個(gè)類型的實(shí)例,那么上述關(guān)系成立,如此層層遞進(jìn),就構(gòu)成了實(shí)例與原型的鏈接。這就是原型鏈的基本概念。

15、繼承
https://www.cnblogs.com/humin...
16、閉包

http://www.ruanyifeng.com/blo...

帶你一分鐘理解閉包--js面向?qū)ο缶幊蹋篽ttp://cnblogs.com/qieguo/p/5...

閉包的概念:有權(quán)訪問(wèn)另一個(gè)作用域的函數(shù)。
第一,閉包是一個(gè)函數(shù)。第二,閉包是一個(gè)能夠訪問(wèn)另一個(gè)函數(shù)作用域

function A(){

  var a=1;
  
  function B(){  //閉包函數(shù),函數(shù)b能夠訪問(wèn)函數(shù)a的作用域。所以,像類似這么樣的函數(shù),我們就稱為閉包
  
  }
}
閉包是指有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域中的變量的函數(shù)
閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。"定義在一個(gè)函數(shù)內(nèi)部的函數(shù)"
它的最大用處有兩個(gè),一個(gè)是可以讀取函數(shù)內(nèi)部的變量,另一個(gè)就是讓這些變量的值始終保持在內(nèi)存中。
閉包:一個(gè)函數(shù)有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域中的變量,即在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)
function sayHi(name) {
    return () => {
       console.log(`Hi! ${name}`)
    }
}
const test = sayHi("xiaoming")
test() // Hi! xiaoming
嚴(yán)格來(lái)說(shuō),JS中所有的函數(shù)都是閉包,因?yàn)?JS 里并沒(méi)有語(yǔ)法關(guān)鍵字限制哪些函數(shù)可以訪問(wèn)外部變量哪些不能,所以所有函數(shù)都會(huì)創(chuàng)建獨(dú)立作用域,亦即所有函數(shù)都是閉包。
JS 的閉包包含以下要點(diǎn):

函數(shù)聲明的時(shí)候,會(huì)生成一個(gè)獨(dú)立的作用域

同一作用域的對(duì)象可以互相訪問(wèn)

作用域呈層級(jí)包含狀態(tài),形成作用域鏈,子作用域的對(duì)象可以訪問(wèn)父作用域的對(duì)象,反之不能;另外子作用域會(huì)使用最近的父作用域的對(duì)象

https://www.cnblogs.com/wangf...
https://blog.csdn.net/gaoshan...
https://www.jianshu.com/p/26c...
https://www.cnblogs.com/cxyin...
http://www.cnblogs.com/xiaoru...
http://www.cnblogs.com/lulupi...

閉包的應(yīng)用場(chǎng)景
https://blog.csdn.net/qq_2113...
https://segmentfault.com/a/11...
https://blog.csdn.net/yingziz...

17、事件委托/事件代理
什么是事件冒泡?怎樣阻止事件冒泡和默認(rèn)事件?事件委托是什么?

冒泡事件即是事件從最底層逐個(gè)經(jīng)過(guò)上面一級(jí)級(jí)事件的過(guò)程,就是冒泡事件。
那么如何有效的阻止冒泡事件的發(fā)生?其實(shí)在非IE瀏覽器中提供了一個(gè)事件對(duì)象 stopPropagation,那么在IE瀏覽器中通過(guò)cancelBubble事件對(duì)象可以阻止。
瀏覽器的默認(rèn)事件就是瀏覽器自己的行為,比如我們?cè)邳c(diǎn)擊的時(shí)候,瀏覽器跳轉(zhuǎn)到指定頁(yè)面。還有,當(dāng)我們滾動(dòng)鼠標(biāo)時(shí)頁(yè)面會(huì)向下滾動(dòng),但我們按空格鍵和按方向鍵時(shí)頁(yè)面也會(huì)向下滾動(dòng),為了更好的用戶體驗(yàn),這時(shí)我們就需要阻止這種行為的發(fā)生。
// 阻止事件冒泡  
function stopBubble(e) {  
  if(e && e.stopPropagation){  
      e.stopPropagation();  
  } else {  
    window.event.cancelBubble = true;  
  }  
};  
// 阻止瀏覽器的默認(rèn)事件  
function stopDefault(e){  
  if(e && e.preventDefault) {  
    e.preventDefault();  
  } else {  
    window.event.returnValue = false;  
  }  
  return false;  
};  

事件模型解釋: https://segmentfault.com/a/11...
Javascript的事件流模型都有什么?如何阻止?

兩種事件模型:捕獲型事件和冒泡型事件
事件流包含三個(gè)階段:事件捕獲階段,處于目標(biāo)階段和事件冒泡階段。首先發(fā)生的是事件捕獲,然后是實(shí)際的目標(biāo)接收到事件,最后階段是冒泡階段。
1、事件:是文檔或?yàn)g覽器窗口中發(fā)生的一些特定的交互瞬間
2、事件流:事件發(fā)生的順序,頁(yè)面中接受事件的順序
3、事件冒泡:(事件從最深的節(jié)點(diǎn)開始,然后逐步向上傳播事件,)事件會(huì)從最內(nèi)層的元素開始發(fā)生,一直向上傳播,直到document對(duì)象。發(fā)生click事件的順序應(yīng)該是p -> div -> body -> html -> document
4、事件捕獲:事件會(huì)從最外層開始發(fā)生,直到最具體的元素。發(fā)生click事件的順序應(yīng)該是document -> html -> body -> div -> p
5、事件代理(事件委托):通過(guò)它你可以把事件處理器添加到一個(gè)父級(jí)元素上,這樣就避免了把事件處理器添加到多個(gè)子級(jí)元素上,給父元素綁定事件,用來(lái)監(jiān)聽子元素的冒泡事件,并找到是哪個(gè)子元素的事件。

事件委托的好處:

事件委托技術(shù)可以避免對(duì)每個(gè)字元素添加事件監(jiān)聽器,減少操作DOM節(jié)點(diǎn)的次數(shù),從而減少瀏覽器的重繪和重排,提高代碼的性能。
使用事件委托,只有父元素與DOM存在交互,其他的操作都是在JS虛擬內(nèi)存中完成的,這樣就大大提高了性能。

https://zhuanlan.zhihu.com/p/...
https://www.cnblogs.com/zhana...
https://www.cnblogs.com/liuga...

jQuery中實(shí)現(xiàn)事件委托的三種方法:
1) $.on: 基本用法:$(".parent").on("click", "a", function () { console.log("click event on tag a"); }),它是 .parent 元素之下的 a 元素的事件代理到$(".parent")之上,只要在這個(gè)元素上有點(diǎn)擊事件,就會(huì)自動(dòng)尋找到.parent元素下的a元素,然后響應(yīng)事件;
2) $.delegate: 基本用法:$(".parent").delegate("a", "click", function () { console.log("click event on tag a"); }),同上,并且還有相對(duì)應(yīng)的$.delegate來(lái)刪除代理的事件;
3) $.live: 基本使用方法:$("a", $(".parent")).live("click", function () { console.log("click event on tag a"); }),同上,然而如果沒(méi)有傳入父層元素$(.parent),那事件會(huì)默認(rèn)委托到$(document)上;(已廢除)

事件委托原理:

事件委托是通過(guò)事件冒泡的原理,利用父級(jí)去觸發(fā)子級(jí)的事件。
如果不用事件委托,將ul下每一個(gè)li都去添加click事件監(jiān)聽,非常麻煩,而且對(duì)于內(nèi)存消耗是非常大的,效率上需要消耗很多性能;
另外就是如果通過(guò)js動(dòng)態(tài)創(chuàng)建的子節(jié)點(diǎn),需要重新綁定事件。
而利用事件委托的話,只需要給父級(jí)綁定一個(gè)事件監(jiān)聽,即可讓每個(gè)li都綁定上相應(yīng)的事件,讓你避免對(duì)特定的每個(gè)節(jié)點(diǎn)添加事件監(jiān)聽器;事件監(jiān)聽器是被添加到它們的父元素上。事件監(jiān)聽器會(huì)分析從子元素冒泡上來(lái)的事件,找到是哪個(gè)子元素的事件。

適合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。

值得注意的是,mouseover和mouseout雖然也有事件冒泡,但是處理它們的時(shí)候需要特別的注意,因?yàn)樾枰?jīng)常計(jì)算它們的位置,處理起來(lái)不太容易。

不適合的就有很多了,舉個(gè)例子,mousemove,每次都要計(jì)算它的位置,非常不好把控,在不如說(shuō)focus,blur之類的,本身就沒(méi)用冒泡的特性,自然就不能用事件委托了。

18、事件冒泡和事件捕獲

什么是事件,IE與火狐的事件機(jī)制有什么區(qū)別? 如何阻止冒泡?
1. 我們?cè)诰W(wǎng)頁(yè)中的某個(gè)操作(有的操作對(duì)應(yīng)多個(gè)事件)。例如:當(dāng)我們點(diǎn)擊一個(gè)按鈕就會(huì)產(chǎn)生一個(gè)事件。是可以被 JavaScript 偵測(cè)到的行為。  
2、ie支持事件冒泡,火狐支持捕獲和冒泡兩種
3.  w3c支持 e.stopPropagation(),IE則是使用e.cancelBubble = true

https://blog.csdn.net/cyqzy/a...
https://www.cnblogs.com/linxu...
https://www.cnblogs.com/alsy/...

IE和DOM事件流的區(qū)別
https://www.cnblogs.com/lucky...

執(zhí)行順序不一樣、
參數(shù)不一樣
事件偵聽函數(shù)不一樣
this指向不一樣

https://www.cnblogs.com/amcy/...
19、JavaScript防XSS攻擊

XSS(Cross Site Scripting),跨站腳本攻擊,是一種允許攻擊者在另外一個(gè)用戶的瀏覽器中執(zhí)行惡意代碼腳本的腳本注入式攻擊。XSS攻擊其實(shí)就是代碼的注入。

XSS危害

通過(guò)document.cookie盜取cookie

使用js或css破壞頁(yè)面正常的結(jié)構(gòu)與樣式

流量劫持(通過(guò)訪問(wèn)某段具有window.location.href定位到其他頁(yè)面)

Dos攻擊:利用合理的客戶端請(qǐng)求來(lái)占用過(guò)多的服務(wù)器資源,從而使合法用戶無(wú)法得到服務(wù)器響應(yīng)。

利用iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻擊)用戶的身份執(zhí)行一些管理動(dòng)作,或執(zhí)行一些一般的如發(fā)微博、加好友、發(fā)私信等操作。

利用可被攻擊的域受到其他域信任的特點(diǎn),以受信任來(lái)源的身份請(qǐng)求一些平時(shí)不允許的操作,如進(jìn)行不當(dāng)?shù)耐镀被顒?dòng)。

如何防止攻擊

編碼,就是轉(zhuǎn)義用戶的輸入,把用戶的輸入解讀為數(shù)據(jù)而不是代碼

校驗(yàn),對(duì)用戶的輸入及請(qǐng)求都進(jìn)行過(guò)濾檢查,如對(duì)特殊字符進(jìn)行過(guò)濾,設(shè)置輸入域的匹配規(guī)則等。

設(shè)置CSP:CSP也是采用白名單的方式來(lái)匹配網(wǎng)頁(yè)的解析和代碼的執(zhí)行,只不過(guò),執(zhí)行的層次上升到了瀏覽器的高度

http://www.cnblogs.com/caizhe...
http://www.cnblogs.com/unclek...
20、適配方案fontsize為什么設(shè)在html不是body

使用rem布局,實(shí)質(zhì)都是通過(guò)動(dòng)態(tài)改寫html的font-size基準(zhǔn)值,來(lái)實(shí)現(xiàn)不同設(shè)備下的良好統(tǒng)一適配

rem是基于root根元素(html)計(jì)算的,html{font-size:62.5%} body{font-size:3rem},rem的實(shí)質(zhì)是等比縮放

https://www.cnblogs.com/axl23...
https://segmentfault.com/a/11...

21、get和post
https://www.cnblogs.com/logsh...

HTTP是什么?HTTP是基于TCP/IP的關(guān)于數(shù)據(jù)如何在萬(wàn)維網(wǎng)中如何通信的協(xié)議。
HTTP的底層是TCP/IP。所以GET和POST的底層也是TCP/IP,也就是說(shuō),GET/POST都是TCP鏈接

GET和POST本質(zhì)上就是TCP鏈接,并無(wú)差別。但是由于HTTP的規(guī)定和瀏覽器/服務(wù)器的限制,導(dǎo)致他們?cè)趹?yīng)用過(guò)程中體現(xiàn)出一些不同。
GET和POST是HTTP請(qǐng)求的兩種基本方法,最直觀的區(qū)別就是GET把參數(shù)包含在URL中,POST通過(guò)request body傳遞參數(shù)
GET和POST還有一個(gè)重大區(qū)別,簡(jiǎn)單的說(shuō):GET產(chǎn)生一個(gè)TCP數(shù)據(jù)包;POST產(chǎn)生兩個(gè)TCP數(shù)據(jù)包。
長(zhǎng)的說(shuō):對(duì)于GET方式的請(qǐng)求,瀏覽器會(huì)把http header和data一并發(fā)送出去,服務(wù)器響應(yīng)200(返回?cái)?shù)據(jù));而對(duì)于POST,瀏覽器先發(fā)送header,服務(wù)器響應(yīng)100 continue,瀏覽器再發(fā)送data,服務(wù)器響應(yīng)200 ok(返回?cái)?shù)據(jù))。
注意: 并不是所有瀏覽器都會(huì)在POST中發(fā)送兩次包,F(xiàn)irefox就只發(fā)送一次。

GET在瀏覽器回退時(shí)是無(wú)害的,而POST會(huì)再次提交請(qǐng)求。
GET產(chǎn)生的URL地址可以被Bookmark,而POST不可以。
GET請(qǐng)求會(huì)被瀏覽器主動(dòng)cache,而POST不會(huì),除非手動(dòng)設(shè)置。
GET請(qǐng)求只能進(jìn)行url編碼,而POST支持多種編碼方式。
GET請(qǐng)求參數(shù)會(huì)被完整保留在瀏覽器歷史記錄里,而POST中的參數(shù)不會(huì)被保留。
GET請(qǐng)求在URL中傳送的參數(shù)是有長(zhǎng)度限制的,而POST么有。
對(duì)參數(shù)的數(shù)據(jù)類型,GET只接受ASCII字符,而POST沒(méi)有限制。
GET比POST更不安全,因?yàn)閰?shù)直接暴露在URL上,所以不能用來(lái)傳遞敏感信息。
GET參數(shù)通過(guò)URL傳遞,POST放在Request body中。

22、http協(xié)議中除了get和post之外還有哪些

根據(jù)HTTP標(biāo)準(zhǔn),HTTP請(qǐng)求可以使用多種方法,其功能描述如下所示。
HTTP1.0定義了三種請(qǐng)求方法: GET、POST、HEAD
HTTP1.1新增了五種請(qǐng)求方法:OPTIONS、PUT、DELETE、TRACE 、CONNECT

23、前端緩存(cookies、localStorage、sessionStorage):https://segmentfault.com/a/11...

1、cookies是服務(wù)器發(fā)送給客戶端的特殊信息,只能保存字符串類型,以文本的形式保存在客戶端,每次請(qǐng)求都帶著它;如果不在瀏覽器設(shè)置過(guò)期時(shí)間,cookie被保存在內(nèi)存中,生命周期隨瀏覽器的關(guān)閉而結(jié)束,這種cookie簡(jiǎn)稱為會(huì)話cookie;如果瀏覽器設(shè)置了過(guò)期時(shí)間,cookie被保存在硬盤中,關(guān)閉瀏覽器,cookie仍存在,直到過(guò)期時(shí)間結(jié)束才消失。

cookie的應(yīng)用場(chǎng)景:

(1)判斷用戶是否登陸過(guò)網(wǎng)站,以便下次實(shí)現(xiàn)自動(dòng)登錄(或記住密碼)。如果我們刪除cookie,每次登錄都必須重新填寫登錄信息,
(2)保存上次登錄時(shí)間等信息。
(3)保存上次查看的頁(yè)面。
(4)瀏覽計(jì)數(shù)。

2、localStorage 的生命周期是永久的,關(guān)閉頁(yè)面或?yàn)g覽器之后localStorage的數(shù)據(jù)也不會(huì)消失。除非localStorage主動(dòng)刪除數(shù)據(jù)。否則數(shù)據(jù)永遠(yuǎn)不會(huì)消失。
3、sessionStorage 的生命周期僅在當(dāng)前會(huì)話下有效,sessionStorage是在同源窗口中始終保存數(shù)據(jù),只要瀏覽器沒(méi)有關(guān)閉,即使刷新頁(yè)面或進(jìn)入同源的另一個(gè)頁(yè)面,數(shù)據(jù)依然存在。但是sessionStorage在瀏覽器關(guān)閉后就會(huì)被銷毀。同時(shí)獨(dú)立打開同一個(gè)頁(yè)面或同一個(gè)窗口,sessionStorage也不是一樣的。
其中l(wèi)ocalStorage 和 sessionStorage 都保存在客戶端,不與服務(wù)器進(jìn)行交互通信。

localStorage 和 sessionStorage 的應(yīng)用場(chǎng)景:

(1)localStorage 常用于長(zhǎng)期登錄(+判斷用戶是否已登錄),適合長(zhǎng)期保存在本地的數(shù)據(jù)。
(2)sessionStorage適用于敏感賬號(hào)一次性登錄。

cookie和session的區(qū)別

cookie數(shù)據(jù)存放在客戶的瀏覽器上,session數(shù)據(jù)放在服務(wù)器上

cookie不是很安全,別人可以分析存放在本地的cookie并進(jìn)行cookie欺騙,考慮*到安全應(yīng)當(dāng)使用session

session會(huì)在一定時(shí)間內(nèi)保存在服務(wù)器上,當(dāng)訪問(wèn)增多,會(huì)比較占用你服務(wù)器的性能,考慮到減輕服務(wù)器性能方面,應(yīng)當(dāng)使用cookie

單個(gè)cookie保存的數(shù)*據(jù)不能超過(guò)4K,很多瀏覽器都限制一個(gè)站點(diǎn)最多保存20個(gè)cookie

建議將登錄信息等重要信息存放為session,其他信息如果需要保留,可以放在cookie中

session保存在服務(wù)器,客戶端不知道其中的信息;cookie保存在客戶端,服務(wù)器能夠知道其中的信息

session中保存的是對(duì)象,cookie中保存的是字符串

session不能區(qū)分路徑,同一個(gè)用戶在訪問(wèn)一個(gè)網(wǎng)站期間,所有的session在任何一個(gè)地方都可以訪問(wèn)到,而cookie中如果設(shè)置了路徑參數(shù),那么同一個(gè)網(wǎng)站中不同路徑下的cookie互相是訪問(wèn)不到的

Cookie和session的作用。區(qū)別、應(yīng)用范圍。Session的工作原理是什么

區(qū)別:
1、cookie數(shù)據(jù)存放在客戶的瀏覽器上,session數(shù)據(jù)放在服務(wù)器上。
2、cookie不是很安全,別人可以分析存放在本地的COOKIE并進(jìn)行COOKIE欺騙考慮到安全應(yīng)當(dāng)使用session。
3、session會(huì)在一定時(shí)間內(nèi)保存在服務(wù)器上。當(dāng)訪問(wèn)增多,會(huì)比較占用你服務(wù)器的性能考慮到減輕服務(wù)器性能方面,應(yīng)當(dāng)使用COOKIE。
4、單個(gè)cookie保存的數(shù)據(jù)不能超過(guò)4K,很多瀏覽器都限制一個(gè)站點(diǎn)最多保存20個(gè)cookie。
5、所以個(gè)人建議:
將登陸信息等重要信息存放為SESSION
其他信息如果需要保留,可以放在COOKIE中

描述一下cookies,sessionStorage,localStorage的區(qū)別

sessionStorage用于本地存儲(chǔ)一個(gè)會(huì)話(session)中的數(shù)據(jù),這些數(shù)據(jù)只有在同一個(gè)會(huì)話中的頁(yè)面才能訪問(wèn)并且當(dāng)會(huì)話結(jié)束后數(shù)據(jù)也隨之銷毀。
因此sessionStorage不是一種持久化的本地存儲(chǔ),僅僅是會(huì)話級(jí)別的存儲(chǔ)。
而localStorage用于持久化的本地存儲(chǔ),除非主動(dòng)刪除數(shù)據(jù),否則數(shù)據(jù)是永遠(yuǎn)不會(huì)過(guò)期的。
**web storage和cookie的區(qū)別**
Web Storage的概念和cookie相似,區(qū)別是它是為了更大容量存儲(chǔ)設(shè)計(jì)的。Cookie的大小是受限的,并且每次你請(qǐng)求一個(gè)新的頁(yè)面的時(shí)候Cookie都會(huì)被發(fā)送過(guò)去,這樣無(wú)形中浪費(fèi)了帶寬,另外cookie還需要指定作用域,不可以跨域調(diào)用。
除此之外,Web Storage擁有setItem,getItem,removeItem,clear等方法,不像cookie需要前端開發(fā)者自己封裝setCookie,getCookie。但是Cookie也是不可以或缺的:Cookie的作用是與服務(wù)器進(jìn)行交互,作為HTTP規(guī)范的一部分而存在 ,而Web Storage僅僅是為了在本地“存儲(chǔ)”數(shù)據(jù)而生。

localStorage、sessionStorage、Cookie的區(qū)別及用法:https://segmentfault.com/a/11...

淺談session,cookie,sessionStorage,localStorage的區(qū)別及應(yīng)用場(chǎng)景:https://www.cnblogs.com/cence...

24、常用的本地存儲(chǔ)-----cookie篇
https://www.cnblogs.com/cxyin...
怎么設(shè)置cookie,怎么設(shè)置cookie以及刪除cookie和cookie詳解:https://www.cnblogs.com/mader...
編寫web端cookie的設(shè)置和獲取方法:https://blog.csdn.net/u010081...
設(shè)置獲取cookie,setCookie,getCookie
https://www.cnblogs.com/zmj-b...
25、javascript用戶密碼加密

md5加密是單向不可逆的,md5 是一種 hash 算法

MD5:信息摘要的一種實(shí)現(xiàn),它可以從任意長(zhǎng)度的明文字符串生成128位的哈希值。即使明文消息只改動(dòng)了一點(diǎn)點(diǎn),生成的結(jié)果也會(huì)完全不同。

第三方支付平臺(tái)如何驗(yàn)證請(qǐng)求的簽名?
1.發(fā)送方和請(qǐng)求方約定相同的字符串拼接規(guī)則,約定相同的密鑰。
2.第三方平臺(tái)接到支付請(qǐng)求,按規(guī)則拼接業(yè)務(wù)參數(shù)和密鑰,利用 MD5 算法生成 Sign。
3.用第三方平臺(tái)自己生成的 Sign 和請(qǐng)求發(fā)送過(guò)來(lái)的 Sign 做對(duì)比,如果兩個(gè) Sign 值一模一樣,則簽名無(wú)誤,如果兩個(gè) Sign 值不同,則信息做了篡改。這個(gè)過(guò)程叫做驗(yàn)簽。

md5原理:https://www.cnblogs.com/secon...

DES對(duì)稱加密

DES加密原理:https://www.cnblogs.com/xqxac...

26、談?wù)勀銓?duì)this的理解

this是js的一個(gè)關(guān)鍵字,隨著函數(shù)使用場(chǎng)合不同,this的值會(huì)發(fā)生變化。但是總有一個(gè)原則,那就是this指的是調(diào)用函數(shù)的那個(gè)對(duì)象。this一般情況下:是全局對(duì)象Global。 作為方法調(diào)用,那么this就是指這個(gè)對(duì)象。

個(gè)人建議,可以先回答this在不同的場(chǎng)合指向的是什么,在來(lái)回答什么時(shí)候用到this,這樣回答的邏輯會(huì)比較好。

this表示當(dāng)前對(duì)象,this的指向是根據(jù)調(diào)用的上下文來(lái)決定的,默認(rèn)指向window對(duì)象,指向window對(duì)象時(shí)可以省略不寫。

this是對(duì)應(yīng)執(zhí)行環(huán)境,在全局作用域下,this默認(rèn)指向window對(duì)象。全局環(huán)境的this始終指向的是window對(duì)象;局部環(huán)境下,對(duì)象函數(shù)調(diào)用,this指向的永遠(yuǎn)是調(diào)用該方法的對(duì)象,哪個(gè)對(duì)象調(diào)用就指向哪個(gè)對(duì)象

顯示綁定就是通過(guò)apply,call,bind,直接將函數(shù)中的this綁定到想要的對(duì)象上

創(chuàng)建一個(gè)構(gòu)造函數(shù)的實(shí)例,構(gòu)造函數(shù)中的this會(huì)綁定到這個(gè)實(shí)例對(duì)象上

This指針作用域:
1)、在全局執(zhí)行環(huán)境中使用this,表示Global對(duì)象,在瀏覽器中就是window對(duì)象。
2)、當(dāng)在函數(shù)執(zhí)行環(huán)境中使用this時(shí),情況就有些復(fù)雜了。如果函數(shù)沒(méi)有明顯的作為非window對(duì)象的屬性,而只是定義了函數(shù),不管這個(gè)函數(shù)是不是定義在另一個(gè)函數(shù)中,這個(gè)函數(shù)中的this仍然表示window對(duì)象。如果函數(shù)顯示地作為一個(gè)非window對(duì)象的屬性,那么函數(shù)中的this就代表這個(gè)對(duì)象。
3)、當(dāng)通過(guò)new運(yùn)算符來(lái)調(diào)用函數(shù)時(shí),函數(shù)被當(dāng)做一個(gè)構(gòu)造函數(shù),this指向構(gòu)造函數(shù)創(chuàng)建出來(lái)的對(duì)象。
注:當(dāng)函數(shù)被調(diào)用時(shí),我們看緊鄰括號(hào)“()”的左邊。如果在括號(hào)的左側(cè)存在一個(gè)引用,傳遞給調(diào)用函數(shù)的“this”值是引用所屬于的那個(gè)對(duì)象,否則this的值就是全局對(duì)象。
var name = "window在手,天下我有!";
var obj = {
  name: "敲代碼的怪蜀黍",
  objBar: {
    name: "BOBO",
    barFun: function(){
      console.log(this.name);
    }
  }
};
 
//()左側(cè)是barFun引用,它指向objBar對(duì)象,所以打印出 “BOBO”
var test1 = obj.objBar.barFun(); //BOBO
 
//()左側(cè)是test2,test2它并不是某個(gè)對(duì)象的引用,所以打印出 “window在手,天下我有!”
var test2 = obj.objBar.barFun;
test2(); //window在手,天下我有!
 
//下面這個(gè)看起來(lái)復(fù)雜,其實(shí)抓住一點(diǎn)就行了:()左側(cè)是testBar,testBar并不屬于某個(gè)對(duì)象的引用,當(dāng)然打印出來(lái)的還是 “window在手,天下我有!”
var test3 = obj.objBar;
var testBar = test3.barFun;
testBar(); //window在手,天下我有!

http://www.ruanyifeng.com/blo...
https://blog.csdn.net/lxcao/a...
https://www.cnblogs.com/liubi...
https://www.cnblogs.com/banzh...
https://www.cnblogs.com/yuanb...

和箭頭函數(shù)的區(qū)別

箭頭函數(shù)中的this:

1.箭頭函數(shù)會(huì)捕獲其所在上下文的 this 值,作為自己的 this 值,自己本身并沒(méi)有this值;
2.箭頭函數(shù)的this永遠(yuǎn)指向其上下文的this,任何方法都改變不了其指向,如call(), bind(), apply()。
3.箭頭函數(shù)作為匿名函數(shù),是不能作為構(gòu)造函數(shù)的,不能使用new
4.箭頭函數(shù)沒(méi)有原型屬性

https://www.jianshu.com/p/8f7...

27、如何規(guī)避javascript多人開發(fā)函數(shù)重名問(wèn)題
https://www.cnblogs.com/zhuzh...

可以開發(fā)前規(guī)定命名規(guī)范,根據(jù)不同開發(fā)人員開發(fā)的功能在函數(shù)前加前綴;
將每個(gè)開發(fā)人員的函數(shù)封裝到類中,調(diào)用的時(shí)候就調(diào)用類的函數(shù),即使函數(shù)重名只要類名不重復(fù)就行;

JS中是沒(méi)有塊級(jí)作用域的只有函數(shù)作用域,盡量少的使用全局變量,盡可能使用局部變量,這不僅會(huì)減少變量重名的幾率,更會(huì)減少內(nèi)存開銷,因?yàn)榫植孔兞恳话愣紩?huì)在函數(shù)結(jié)束后自動(dòng)銷毀釋放出內(nèi)存,而全局變量會(huì)直到進(jìn)程結(jié)束才會(huì)被銷毀,其次,當(dāng)我們需要一個(gè)作用域來(lái)關(guān)住變量時(shí)一般會(huì)用一個(gè)匿名函數(shù)來(lái)充當(dāng)這個(gè)作用域。

用類來(lái)封裝子頁(yè), 定義一個(gè)空對(duì)象,變量和方法都掛載到了不同的對(duì)象上,這無(wú)形中就給每個(gè)同名變量和方法增加了一個(gè)頂部命名空間,這樣可以最大化的減少代碼耦合的幾率,項(xiàng)目也容易維護(hù)。

// A同學(xué)負(fù)責(zé)的工作人員信息
var A = {} //定義一個(gè)空對(duì)象
A.name = "tom";
A.gender = "male";
A.age = 30;
A.showName = function() {
    alert(this.name);
}
A.showAge = function() {
    alert(this.age);
}

// B同學(xué)負(fù)責(zé)的老師信息
var B = {}
B.name = "Jack";
B.gender = "male";
B.age = 28;
B.showName = function() {
    alert(this.name);
}
B.showAge = function() {
    alert(this.age);
}

// C同學(xué)負(fù)責(zé)的學(xué)生信息
var C = {}
C.name = "Lucy";
C.gender = "female";
C.age = 17;
C.showName = function() {
    alert(this.name);
}
C.showAge = function() {
    alert(this.age);
}

https://www.cnblogs.com/leftf...
https://www.cnblogs.com/luoge...

命名空間
封閉空間
js模塊化mvc(數(shù)據(jù)層、表現(xiàn)層、控制層)
seajs
變量轉(zhuǎn)換成對(duì)象的屬性
對(duì)象化

解決全局變量命名空間變量名重復(fù)沖突(技巧)

只在函數(shù)里面聲明變量。雖然有時(shí)候也不是絕對(duì)可行,但是函數(shù)級(jí)作用域可以防止其本地變量跟其他變量發(fā)生沖突。

只聲明一個(gè)全局對(duì)象,然后把本來(lái)想作為全局變量的值都作為這個(gè)對(duì)象的屬性。

var Vis = {};   //聲明空的全局對(duì)象
Vis.id = 1;
Vis.name = "dashuaibi";
// 這樣所有的變量都被關(guān)在了全局對(duì)象Vis里面,因此就不會(huì)再污染全局命名空間

28、編寫自己的jquery組件
https://blog.csdn.net/54power...
29、javascript標(biāo)簽到底是應(yīng)該放在頭部還是尾部?

一般地:
js是立即交互性優(yōu)先的頂部
延遲交互性稍后的尾部。
javascript標(biāo)簽放在尾部當(dāng)瀏覽器解析到該元素時(shí),會(huì)暫停其他資源的下載和處理,直到將該資源加載、編譯、執(zhí)行完畢,圖片和框架等元素也如此,類似于將所指向資源嵌入當(dāng)前標(biāo)簽內(nèi)。
但在某種情況下也覺(jué)得放在頭部比較好,比如一個(gè)給頁(yè)面中的某個(gè)元素添加了事件的js腳本。頁(yè)面出來(lái)了但是js沒(méi)加載完的那段時(shí)間,用戶對(duì)此元素做事件操作的時(shí)候就出不來(lái)應(yīng)該有的效果。
現(xiàn)在比較傾向于放在頭部,做一些優(yōu)化的工作盡量讓js加載快一點(diǎn)。
如果放入html的head中,則頁(yè)面加載前該js腳本就會(huì)被加載入頁(yè)面,而放入body中,則會(huì)按照頁(yè)面從上倒下的加載順序來(lái)運(yùn)行javascript的代碼~~~ 所以我們可以把js外部引入的文件放到頁(yè)面底部,來(lái)讓js最后引入,從而加快頁(yè)面加載速度

30、創(chuàng)建一個(gè)對(duì)象

function Person(name, age) {
        this.name = name;
        this.age = age;
        this.sing = function() { 
        alert(this.name)
         } 
 }
var Person = function(name, age){
    //共有屬性
    this.name = name;
    this.age = age;
    //共有方法
    this.sayName = function(){
        console.log(this.name);
    };
}

31、封裝一個(gè)簡(jiǎn)單的javascript類

//函數(shù)聲明,然后使用對(duì)象或數(shù)組訪問(wèn)
function Person() {
   this.name = "jee";
   this.age = 25;
   this.getName = function() {
      return this.name;
   }
} 
var person = new Person();
alert(person.age);
alert(person.getName());

32、答案是多少?

(function(x){
    delete x;
    alert(x);
})(1+5);

1)delete是用來(lái)刪除對(duì)象的屬性的,它不能夠刪除函數(shù)中傳遞的參數(shù)
2)所以這里delete x這句其實(shí)并沒(méi)有什么軟用,函數(shù)正常執(zhí)行傳參及返回參數(shù);
當(dāng)然,刪除失敗也不會(huì)報(bào)錯(cuò),所以代碼運(yùn)行會(huì)彈出“6”。

var Employee = {
  age: 28,
  name: "abc",
  designation: "developer"
}

console.log(delete Employee.name);   // returns true
console.log(delete Employee.age);    // returns true

// 當(dāng)試著刪除一個(gè)不存在的屬性時(shí)
// 同樣會(huì)返回true
console.log(delete Employee.salary); // returns true

https://blog.csdn.net/travelz...
33、模塊化怎么做?

立即執(zhí)行函數(shù),不暴露私有成員
var module1 = (function(){
    var _count = 0;
    var m1 = function(){
      //...
    };
    var m2 = function(){
      //...
    };
    return {
      m1 : m1,
      m2 : m2
    };
  })();

34、js延遲加載的方式有哪些(寫出異步加載js方案)?

JS延遲加載,也就是等頁(yè)面加載完成之后再加載 JavaScript 文件。 
JS延遲加載有助于提高頁(yè)面加載速度。

http://www.php.cn/js-tutorial...

defer和async
注釋:有多種執(zhí)行外部腳本的方法:
如果 async="async":腳本相對(duì)于頁(yè)面的其余部分異步地執(zhí)行(當(dāng)頁(yè)面繼續(xù)進(jìn)行解析時(shí),腳本將被執(zhí)行)
如果不使用 async 且 defer="defer":腳本將在頁(yè)面完成解析時(shí)執(zhí)行
如果既不使用 async 也不使用 defer:在瀏覽器繼續(xù)解析頁(yè)面之前,立即讀取并執(zhí)行腳本
動(dòng)態(tài)創(chuàng)建DOM方式(創(chuàng)建script,插入到DOM中,加載完畢后callBack,用的最多)

按需異步載入js(ajax異步加載):http://blog.csdn.net/lxcao/ar...

異步加載和延遲加載
https://www.cnblogs.com/mylan...

35、new操作符具體干了什么

new 操作符新建了一個(gè)空對(duì)象,這個(gè)對(duì)象原型指向構(gòu)造函數(shù)的prototype,執(zhí)行構(gòu)造函數(shù)后返回這個(gè)對(duì)象。

https://www.jianshu.com/p/354...
https://developer.mozilla.org...
https://www.cnblogs.com/onepi...

1、創(chuàng)建一個(gè)空對(duì)象,并且 this 變量引用該對(duì)象,同時(shí)還繼承了該函數(shù)的原型。
2、屬性和方法被加入到 this 引用的對(duì)象中。
3、新創(chuàng)建的對(duì)象由 this 所引用,并且最后隱式的返回 this 。
var obj  = {};
obj.__proto__ = Base.prototype;
Base.call(obj);

36、stopPropagation, preventDefault 和 return false 的區(qū)別

事件在特定節(jié)點(diǎn)執(zhí)行完之后不再傳遞,可以使用事件對(duì)象的 stopPropagation() 方法。
// 在彈出對(duì)話框上點(diǎn)擊時(shí), 不進(jìn)行任何頁(yè)面操作, 并阻止冒泡
document.getElementById("dialog").onclick = function(ev) {
    ev.stopPropagation();
};
// 在 documentElement 節(jié)點(diǎn)上監(jiān)聽到點(diǎn)擊事件時(shí), 隱藏對(duì)話框
document.documentElement.onclick = function(ev) {
    document.getElementById("dialog").style.display = "none";
};
使用 preventDefault() 阻止后面將要執(zhí)行的瀏覽器默認(rèn)動(dòng)作。
W3C 首頁(yè)鏈接
return false的作用
退出執(zhí)行,return false 之后的所有觸發(fā)事件和動(dòng)作都不會(huì)被執(zhí)行。有時(shí)候 return false 可以用來(lái)替代 stopPropagation() 和preventDefault()。return false 不但阻止事件,還可以返回對(duì)象,跳出循環(huán)等... 方便地一刀切而不夠靈活,濫用易出錯(cuò).

https://segmentfault.com/a/11...

37、js的常見(jiàn)內(nèi)置對(duì)象類:

Date,Array,Math、Number、Boolean、String、Array、RegExp、Function...

http://www.cnblogs.com/lianqi...
https://www.cnblogs.com/wqc57...

38、如何判斷一個(gè)對(duì)象是否屬于某個(gè)類?

instanceof 運(yùn)算符:instanceof 運(yùn)算符要求其左邊的運(yùn)算數(shù)是一個(gè)對(duì)象,右邊的運(yùn)算數(shù)是對(duì)象類的名字或構(gòu)造函數(shù)。如果 object 是 class 或構(gòu)造函數(shù)的實(shí)例,則 instanceof 運(yùn)算符返回 true。如果 object 不是指定類或函數(shù)的實(shí)例,或者 object 為 null,則返回 false。instanceof方法可以判斷變量是否是數(shù)組類型,但是只限同一全局環(huán)境之內(nèi),在一個(gè)頁(yè)面有多個(gè)iframe的情況下,instanceof失效。
       if(a instanceof Person){
           alert("yes");
       }

39、WEB應(yīng)用從服務(wù)器主動(dòng)推送Data到客戶端有那些方式?

html5 websoket
WebSocket通過(guò)Flash
XHR長(zhǎng)時(shí)間連接
XHR Multipart Streaming
不可見(jiàn)的Iframe
閱讀需要支付1元查看
<