//基本數據類型
console.log("1" instanceof String); //false
console.log(1 instanceof Number); //false
console.log(true instanceof Boolean); //false
//引用數據類型
console.log([] instanceof Array); //true
console.log(function(){} instanceof Function); //true
console.log({} instanceof Object); //true複製代碼
console.log(("1").constructor === String); //true
console.log((1).constructor === Number); //true
console.log((true).constructor === Boolean); //true
console.log(([]).constructor === Array); //true
console.log((function(){}).constructor === Function); //true
console.log(({}).constructor === Object); //true
console.log((null).constructor === Null); //報錯
console.log((undefined).constructor === Undefined); //報錯複製代碼
function Fn(){};
Fn.prototype=new Array();
var f=new Fn();
console.log(f.constructor===Fn); //false
console.log(f.constructor===Array); //true複製代碼
console.log(Object.prototype.toString.call(1)); //[object Number]
console.log(Object.prototype.toString.call("1")); //[object String]
console.log(Object.prototype.toString.call(true)); //[object Boolean]
console.log(Object.prototype.toString.call([])); //[object Array]
console.log(Object.prototype.toString.call(function(){})); //[object Function]
console.log(Object.prototype.toString.call({})); //[object Object]
console.log(Object.prototype.toString.call(null)); //[object Null]
console.log(Object.prototype.toString.call(undefined)); //[object Undefined]複製代碼
/第一種
function myFunction(){
}
//定義函數的字符串,函數名本質是變量名,指向某個function的引用。
console.log(myFunction);
//function
console.log(typeof myFunction)
//第二種
var myFunction = new Function(
"num1"
"num2"
"var sum = num1 + num2;return sum"
)
console.log(myFunction(10,20))複製代碼
var arr = [1,36,52,23,48,96,5];
//第一種:
function arrSort(a,b){
return a - b;
}
console.log(arr.sort(arrSort));
//第二種:冒泡排序
//思想:讓數組當中相鄰的兩個數進行比較,數組當中比較小的數值向下沉,數值比較大的向上浮!
// 外層for循環控制循環次數,內層for循環控制相鄰的兩個元素進行比較。
function bubbleSort(arr){
for(var i = 0;i < arr.length-1;i++){
for(var j = 0;j < arr.length-1-i;j++){
if(arr[j] > arr[j+1]){
swap(arr,j,j+1)
}
}
}
return arr;
}
function swap(arr,i,j){
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
console.log(bubbleSort(arr));
//第三種:選擇排序
//思想:以起始元素爲基準,再從剩餘的未排序的元素中挨個與起始元素進行比較,找到剩餘未排序元素中
// 最小的一個與之交換位置。重複此步驟。
function selectSort(arr){
for(var i = 0;i < arr.length-1;i++){
for(var j = i+1;j < arr.length;j++){
if(arr[i] > arr[j]){
awap(arr,i,j)
}
}
}
return arr;
}
function swap(arr,i,j){
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
console.log(selectSort(arr))
//第四種:選擇排序2
function quickSort(arr){
for(var i = 0;i < arr.length-1;i++){
var num = arr[i];
var index = i;
for(var j = i+1;j < arr.length;j++){
if(num > arr[j]){
num = arr[j];
index = j;
}
}
if(index != i){
swap(arr,i,index);
}
}
return arr;
}
function swap(arr,i,j){
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
var arr = [23,56,4,89,556,114,1];
console.log(quickSort(arr));
//第五種:快速排序
//一、從數組中取出一個數做爲基準。在原數組中進行移動,將大於基準的數放到基準的右邊,小於基準的數放到
// 基準左邊,在基準左右造成兩個子數組。在左右子數組中反覆執行步驟一、2。直到全部子數組只剩下一個數。
function quickSort(arr,i,j){
if(i < j){
let left = i;
let right = j;
let pivot = arr[left];
while(i < j){
while(arr[j] >= pivot && i < j){
j--;
}
if(i < j){
arr[i++] = arr[j];
}
while(arr[i] <= pivot && i < j){
i++;
}
if(i < j){
arr[j--] = arr[i]
}
}
arr[i] = pivot;
quickSort(arr,left,i-1);
quickSort(arr,i+1,right);
return arr;
}
}
let arr = [23,56,4,89,556,114,1];
console.log(quickSort(arr,0,arr.length-1));
//快速排序(for循環)
function quickSort(arr){
//若是數組的長度小於等於1,則直接返回這個數組
if(arr.length <= 1){
return arr;
}
//選擇基準數(四捨五入)
var pivotIndex = Math.floor(arr.length/2);
//將基準數與原數組分離
var pivot = arr.splice(pivotIndex,1)[0];
var left = [];
var right = [];
for(var i = 0;i < arr.length;i++){
if(arr[i] <= pivot){
left.push(arr[i]);
}else{
right.push(arr[i]);
}
}
return quickSort(left).concat(pivot,quickSort(right));
}
let arr = [23,56,4,89,556,114,1];
console.log(quickSort(arr));複製代碼
深拷貝和淺拷貝是針對複雜數據類型來講的,淺拷貝只拷貝一層,而深拷貝是層層拷貝;
javascript
//拷貝1層(測試)------------------------------------------------------------
//Object.assign()拷貝方法
//拷貝{}
a = {name:"張三"};
b = Object.assign({},a);
b.name = "李四"; //拷貝完以後進行改變屬性,測試拷貝的屬性值改變原數據是否改變。
console.log(a,b);
//輸出:{name:"張三"}
{name:"李四"} (拷貝成功)
//拷貝[]
a = ["1","2","3"];
b = Object.assign([],a);
b[1]="hello";
console.log(a,b)
//輸出:["1","2","3"]
["1","hello","3"] (拷貝成功)
//for in拷貝方法
var copy = function(a){
var res = a.constructor();
for(var key in a){
if(a.hasOwnProperty(key)){
res[key] = a[key]
}
}
return res;
}
a = {name:"123",people:{name:"456"}};
b = copy(a);
b.people.name="hello";
a = ["a","b","c"];b = copy(a);
b[1] = 0;//拷貝完以後進行改變屬性,測試拷貝的屬性值改變原數據是否改變。
console.log(a,b)
//輸出:["a","b","c"]
["a","0","c"] (拷貝成功)
//拷貝2層(測試)-------------------------------------------------------------
//Object.assign()拷貝方法
a = {name:"abc",people:{name:"張三"}};
b = Object.assign({},a);
b.people.name="李四";
console.log(a,b)
//輸出:{name:"abc",people:{name:"李四"}}
{name:"abc",people:{name:"李四"}} (拷貝失敗) //for in拷貝方法
var copy = function(a){
var res = a.constructor();
console.log(res);
for(var key in a){
if(a.hasOwnProperty(key)){
res[key] = a[key]
}
}
return res;
}
a = ["a","b",{name:"張三"}];b = copy(a);b[2].name="李四";
console.log(a,b)
//輸出:{name:"abc",people:{name:"李四"}}
{name:"abc",people:{name:"李四"}} (拷貝失敗)
複製代碼
//JSON.parse(JSON.stringify(obj))方法拷貝2層
var deepCopy = function(a){
return JSON.parse(JSON.stringify(a));
}
var a = {name:"aaa",people:{name:"abc"}};
var b = deepCopy(a);
b.people.name = "def";
console.log(a,b)
//輸出:{name:"aaa",people:{name:"abc"}}
{name:"aaa",people:{name:"def"}} (拷貝成功)//JSON.parse(JSON.stringify(obj))方法拷貝3層
var deepCopy = function(a){
return JSON.parse(JSON.stringify(a))
}
var a = [1,2,{name:"aaa"}];
var b = deepCopy(a);
b[2].name = "bbb";
console.log(a,b);
//輸出:["1","2",{name:"aaa"}]
["1","2",{name:"bbb"}] (拷貝成功)
//JSON.parse(JSON.stringify(obj))拷貝函數的時候
var deepCopy = function(a){
return JSON.parse(JSON.stringify(a));
}
var a = {name:"aaa",fun:function(){console.log(1)},age:undefined};
var b = deep(a);
b.name = "bbb"
console.log(a,b);
//輸出:{name:"aaa",fun:function(){console.log(1)},age:undefined};
{name:"bbb"} (拷貝失敗,只拷貝到了name屬性)
//JSON.parse(JSON.stringify(obj))拷貝原型鏈上的屬性
function Person(name){
this.name=name;
}
var a = new Person("Bob");
var b = deep(a);
console.log(a.constructor == Person); //true
console.log(b.constructor == Object); //true
//先不說拷貝出的值,光是數據類型已經不一樣了 (拷貝失敗)
console.log(a,b)
//輸出:
// Person{name:"Bob"} {name:"Bob"}複製代碼
深拷貝(完美拷貝):css
function deepClone(obj,hash = new WeakMap()){ //遞歸拷貝
if(obj instanceof RegExp) return new RegExp(obj);
if(obj instanceof Date) return new Date(obj);
if(obj === null || typeof obj !== 'object'){
//若是不是複雜數據類型,直接返回
return obj;
}
if(hash.has(obj)){
return hash.get(obj);
}
//若是obj是數組,那麼 obj.constructor 是 [Function: Array]
//若是obj是對象,那麼 obj.constructor 是 [Function: Object]
let t = new obj.constructor();
hash.set(obj,t);
for(let key in obj){
//遞歸
if(obj.hasOwnProperty(key)){ //是不是自身的屬性
t[key] = deepClone(obj[key],hash);
}
}
return t;
}
var show = {
name:"Bob",
fun:function(){console.log(1)},
age:null,
pic:undefined,
}
var show2 = deepClone(show);
show2.name="Mary"
console.log(show,show2) //拷貝成功,完美拷貝 複製代碼
繼承:強烈推薦各位去這個網站 github.com/YvetteLau/B…html
function argText(a,b,c){
var actual = arguments.length; //實際傳參個數
var hope = argText.length //指望傳參個數
console.log(actual,hope);
//轉換數組:
var args = [].slice.call(arguments); //第一種
var args = Array.prototype.slice.call(arguments); //第二種
let args = Array.from(arguments); //第三種
let args = [...arguments]; //第四種
console.log(args)
}
argText(1,2)
//輸出: 2 3 複製代碼
function argText(){
var e = arguments.callee.toString();
console.log(e);
}
argText(); 複製代碼
function argText(){
if(argText.caller){
var caller = argText.caller.toString();
console.log(caller);
}else{
console.log("no caller");
}
}
function handler(){
argText();
}
function copyHandler(){
handler();
}
argText()
//輸出: no caller
handler()
//輸出: function handler(){argText();}
copyHandler();
//輸出: function handler(){argText();} 複製代碼
//使用閉包找到dome元素的下標
var oLi = document.getElementsByTagName("li");
// 使用閉包後點擊對應的li標籤,會返回對應的下標
for(var i = 0;i < oLi.length;i++){
//閉包方式一
(function(j){
oLi[j].onclick = function(){
console.log(j)
}
})(i);
//閉包方式二
oLi[i].onclick = function(index){
return function(){
console.log(index);
}
}(i);
//不使用閉包的狀況下,輸出值所有爲(length+1)
oLi[i].onclick = function(){
console.log(i);
}
}
複製代碼
//一、every()
var arr = [1,56,80,5];
var main = arr.every(n => n > 0);
console.log(main) //輸出:true
//二、some()
var arr = [1,-56,80,-5];
var main = arr.some(n => n > 0);
console.log(main) //輸出:true
//三、reducer()
var arr = [10,20,30,40]
let result = arr.reduce(function(prev,next,index,arr){
return prev + next;
})
console.log(result); //輸出:100複製代碼
//一、Array.from() -- Array.of()
var arrayLink = {
"0":"a",
"1":"b",
"2":"c",
length:3
}
var arr = Array.from(arrayLink)
console.log(arr) // 輸出: [a,b,c]
console.log(Array.from("abcdefg")) //輸出:["a", "b", "c", "d", "e", "f", "g"]
console.log(Array.of(1,2,3,4,5)) //輸出: [1, 2, 3, 4, 5]
//二、copyWithin()
var arr = [1,2,3,4,5];
var main = arr.copyWithin(0,3);
console.log(main); //輸出:[4,5,3,4,5]
//三、find()
var arr = [1,-5,2,9,-6];
var main = arr.find(n => n < 0);
console.log(main); //輸出:-5
//四、fill()
var arr = ["a","b","c","d"];
console.log(arr.fill(7,1,2));//輸出:["a",7,"c","d"]
//五、keys() values() entries()
var arr = ["a","b","c","d"];
for(let index of arr.keys()){
console.log(index);
}
for(let elem of arr.values()){
console.log(elem);
}
for(let [index,elem] of arr.entries()){
console.log(index,elem);
}
//六、includes()
let arr = [12,34,223,45,67]
console.log(arr.includes(45)) //輸出:true
[1, 2, NaN].includes(NaN) // true
[1, 2, NaN].indexOf(NaN) // -1
//七、Map
var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 95
//初始化Map須要一個二維數組,或者直接初始化一個空Map。Map具備如下方法:
var m = new Map(); // 空Map
m.set('Adam', 67); // 添加新的key-value
m.set('Bob', 59);
m.has('Adam'); // 是否存在key 'Adam': true
m.get('Adam'); // 67
m.delete('Adam'); // 刪除key 'Adam'
m.get('Adam'); // undefined
//因爲一個key只能對應一個value,因此,屢次對一個key放入value,後面的值會把前面的值沖掉:
var m = new Map();
m.set('Adam', 67);
m.set('Adam', 88);
m.get('Adam'); // 88
//八、Set
//要建立一個Set,須要提供一個Array做爲輸入,或者直接建立一個空Set:
var s1 = new Set(); // 空Set
var s2 = new Set([1, 2, 3]); // 含1, 2, 3
//重複元素在Set中自動被過濾:
var s = new Set([1, 2, 3, 3, '3']);
s; // Set {1, 2, 3, "3"} 注意:數字3和字符串'3'是不一樣的元素
//經過add(key)方法能夠添加元素到Set中,能夠重複添加,但不會有效果:
s.add(4);
s; // Set {1, 2, 3, 4}
s.add(4);
s; // 仍然是 Set {1, 2, 3, 4}
//經過delete(key)方法能夠刪除元素:
var s = new Set([1, 2, 3]);
s; // Set {1, 2, 3}
s.delete(3);
s; // Set {1, 2}複製代碼
ES6新增數據類型:Symbol前端
ES10新增數據類型BigInt:BigInt數據類型的目的是比Number數據類型支持的範圍更大的整數值vue
let [a,b,c,d] = [1,2,3,4];
console.log(a,b,c,d);
let [x,y,...z] = [1,2,3,4,5,6,7,8];
console.log(x,y,z);
let arr = [1,2,3,4,5];
console.log(...arr); //輸出:1 2 3 4 5
let [, , third] = ["foo","bar","baz"];
console.log(third); //輸出: baz
let [x,y,...z] = ["a"];
console.log(x,y,z); //輸出:"a" undefined []
//報錯:
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
let [foo = true] = [];
console.log(foo) //輸出: true
let [x = 1] = [undefined];
let [y = 1] = [null];
console.log(x) //輸出: 1
console.log(y) //輸出: 1
複製代碼
let {foo,bar} = {bar:"acb",foo:"dce"};
console.log(foo,bar); //輸出:dce abc
let {baz} = {foo:"aaa",bar:"bbb"};
console.log(baz); //輸出:undefined
let {foo:baz} = {foo:"aaa",bar:"bbb"};
console.log(baz); //輸出:aaa
console.log(foo); //輸出:報錯
let x;
{x} = {x:1} //輸出:報錯
let x;
({x} = {x:1});
console.log(x) //輸出:1複製代碼
const [a,b,c,d,e] = "hello";
console.log(a,b,c,d,e) //輸出:h e l l o
let {length : len} = "hello";
console.log(len); //輸出: 5複製代碼
function add([x,y]){
return x + y;
}
console.log(add([1,2])); //輸出:3複製代碼
(重點)解構賦值的用處:java
用處1:交換兩個變量的值react
let a = 10,b = 20;
console.log([a,b] = [b,a]);複製代碼
用處2:從函數返回多個值jquery
function fn(){
return [1,2,3,4,5];
}
var [a,b,c,d,e] = fn();
console.log(a,b,c,d,e);複製代碼
用處3:函數參數的定義ios
function fn3([x,y,z]){
return x+y+z;
}
console.log(fn3([4,5,6]))複製代碼
用處4:函數參數的默認值nginx
function fn4([x=1,y=2,z=3]){
return x+y+z;
}
console.log(fn4([4,5,6]))複製代碼
用處5:提取JSON數據
var dataJson = {
"id":1,
"status":"ok",
"data":[1,2,3,4]
}
var {id,status,data:arr} = dataJson;
console.log(id,status,arr);
//輸出: 1 "ok" [1,2,3,4]複製代碼
用處6:遍歷Set、Map數據結構
var map = new Map();
map.set("first","hello");
map.set("second","world");
console.log(map);
for(var [key,value] of map){
console.log(key+"is:"+value)
}複製代碼
用處7:輸入模塊的指定方法
var {sourceSort,sourceNumber} = require("soure-map")複製代碼
var arr = [1,2,45,44,45,2,89,1,1,2,1,2];複製代碼
第一種:new Set()
var box = Array.from(new Set(arr));
var box = [...new Set(arr)];
console.log(box);複製代碼
第二種:indexOf()
var box = [];
for(var i = 0;i < arr.length;i++){
if(box.indexOf(arr[i]) == -1){
box.push(arr[i])
}
}
console.log(box);複製代碼
第三種:splice()
for(var i = 0;i < arr.length;i++){
for(var j = i+1; j < arr.length;j++){
if(arr[i] == arr[j]){
arr.splice(j,1);
}
}
}
console.log(arr);複製代碼
第四種:sort()+splice()
arr.sort();
for(var i = 0; i < arr.length;i++){
if(arr[i] == arr[i+1]){
arr.splice(i,1);
i--;
}
}
console.log(arr);複製代碼
第五種:遞歸函數
Array.prototype.unique = function(){
var arr = this;
len = arr.length;
arr.sort(function(a,b){
return a - b;
})
function loop(index){
if(index >= 1){
if(arr[index] === arr[index-1]){
arr.splice(index,1);
}
loop(index-1);
}
}
loop(len-1);
return arr;
}
var b = arr.unique();
console.log(b);複製代碼
簡單寫法如上,還有不少寫法,在此不一一列舉。
var x = 5 ** 3; // 5的三次方
console.log(x); //輸出: 125複製代碼
var obj = {
name:"Bob",
age:25
}
var arr = Object.entries(obj)
console.log(arr); //輸出:[['name', 'Bob'], ['age', 25]]
var arr = ["Bob","Tom"];
var Create = Object.entries(arr);
console.log(Create); //輸出:[['0', 'Bob'], ['1', 'Tom']]複製代碼
var obj = {
name:"Bob",
age:25
}
var arr = Object.values(obj);
console.log(arr); //輸出:["Bob", 25]
var obj = {
2:"a",
1:"b",
3:"c"
}
var arr = Object.values(obj);
console.log(arr); //輸出:["b", "a", "c"]
var obj = [1,3];
var arr = Object.values(obj);
console.log(arr); //輸出:[1,3]複製代碼
var str = "create"
var newStr1 = str.padStart(10,"x");
var newStr3 = str.padStart(6,"x");
var newStr2 = str.padEnd(10,"x");
var newStr4 = str.padEnd(6,"x");
console.log(newStr1,newStr2,newStr3,newStr4)
//輸出:xxxxcreate createxxxx create create複製代碼
var obj1 = {name:"Bob"};
var obj2 = {age:25};
var newObj = Object.assign(obj1,obj2);
console.log(newObj); //輸出: {name: "Bob", age: 25}複製代碼
//Generator函數:
function* add(){
yield "1";
yield "2";
yield "3";
reutrn;
}
var h = add();
console.log(h.next()); //輸出: {value:"1",done:false}
console.log(h.next()); //輸出: {value:"2",done:false}
console.log(h.next()); //輸出: {value:"3",done:false}
console.log(h.next()); //輸出: 報錯
//若是去掉return 則,輸出:{value: undefined, done: true}複製代碼
(強烈推薦)原文連接:mp.weixin.qq.com/s/TY6LbYQDy…
推薦學會前4種,瞭解後6種
function CreatePerson(){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sayName = function(){
return this.name;
}
return obj;
}
var p1 = new CreatePerson("Bob",28);
var p2 = new CreatePerson("Tom",25);複製代碼
var Singleton = function(name){ //單體模式
this.name = name;
this.instance = null;
}
Singleton.prototype.getName = function(){
return this.name;
}
function getInstance(name){ //獲取實例對象
if(!this.instance){
this.instance = new Singleton(name);
}
return this.instance;
}
//測試單體模式
var a = getInstance("Bob");
var b = getInstance("Tom");
console.log(a); //輸出:Singleton {name: "Bob", instance: null}
console.log(b); //輸出:Singleton {name: "Bob", instance: null}
console.log(a === b); //輸出:true複製代碼
var singleMode = (function(){
var privateNum = 112; //建立私有變量
function privateFunc(){
//實現本身業務邏輯的代碼
}
//返回一個對象包含公有方法和屬性
return {
publicMethod1:publicMethod1,
publicMethod2:publicMethos1,
}
})()複製代碼
//好比如今京東ceo想送給奶茶妹一個禮物,可是呢假如該ceo很差意思送,或者因爲工做忙沒有時間送,
//那麼這個時候他就想委託他的經紀人去作這件事
var TeaAndMilkGirl = function(name) { // 先申明一個奶茶妹對象
this.name = name;
};
var Ceo = function(girl) { // 這是京東ceo先生
this.girl = girl;
this.sendMarriageRing = function(ring) { // 送結婚禮物 給奶茶妹
console.log("Hi " + this.girl.name + ", ceo送你一個禮物:" + ring);
}
};
var ProxyObj = function(girl){ // 京東ceo的經紀人是代理,來代替送
this.girl = girl;
this.sendGift = function(gift) { // 經紀人代理送禮物給奶茶妹
(new Ceo(this.girl)).sendMarriageRing(gift); // 代理模式負責本體對象實例化
}
};
// 初始化
var proxy = new ProxyObj(new TeaAndMilkGirl("奶茶妹"));
proxy.sendGift("結婚戒"); // Hi 奶茶妹, ceo送你一個禮物:結婚戒複製代碼
參考網站:blog.csdn.net/song_mou_xi…
var xhr; //建立ajax對象
if(window.XMLHttpRequest){ //兼容IE
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open("get",url,true); //創建鏈接
xhr.send(); //發送
xhr.onreadystatechange = function(){ //獲取數據
if(xhr.readyState == 4 && xhr.status == 200){
var data = JSON.parse(xhr.responseText);
}
}複製代碼
//懶加載簡單代碼實現
//《JS代碼》
window.onload = function(){
//獲取當前瀏覽器視口高度
var viewHeight = document.documentElement.clientHeight;
console.log(viewHeight);
//鼠標滾動回調
function lazyload(){
var img = document.getElementsByClassName("img");
for(let item of img){
//獲取每張圖片距離頂部的距離
var imgHeight = item.getBoundingClientRect();
console.log(imgHeight)
//判斷當圖片出如今視口160px的時候把地址放入src中,顯示出圖片
if(imgHeight.top < (viewHeight - 10)){
item.src = item.getAttribute("data-original");
}
}
}
lazyload(); //頁面加載時把當前視口中的圖片加載進來
document.addEventListener("scroll",lazyload);
}
//《HTML代碼》
<img class="img" lazyload="true" data-origin="圖片http地址">
<img class="img" lazyload="true" data-origin="圖片http地址"><img class="img" lazyload="true" data-origin="圖片http地址"><img class="img" lazyload="true" data-origin="圖片http地址"><img class="img" lazyload="true" data-origin="圖片http地址">複製代碼
//預加載簡單代碼實現
//style
#box{width:0;height:30px;background:red;transition:1s;}
//html
<div id="box"></div>
<ul>
<li><img src="圖片http地址"></li>
<li><img src="圖片http地址"></li>
<li><img src="圖片http地址"></li> <li><img src="圖片http地址"></li>
<li><img src="圖片http地址"></li> <li><img src="圖片http地址"></li> <li><img src="圖片http地址"></li> <li><img src="圖片http地址"></li>
</ul>
//JS代碼
window.onload = function(){
var oBox = document.getElementById("box");
var arr = [
"https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3916481728,2850933383&fm=26&gp=0.jpg",
"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=291222564,3369340489&fm=26&gp=0.jpg",
"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3974834430,2578081919&fm=26&gp=0.jpg",
"http://img3.imgtn.bdimg.com/it/u=2332284096,307149879&fm=26&gp=0.jpg",
"http://img0.imgtn.bdimg.com/it/u=2667939876,1138687338&fm=26&gp=0.jpg",
"http://img0.imgtn.bdimg.com/it/u=2981065320,3294183154&fm=26&gp=0.jpg",
"http://img4.imgtn.bdimg.com/it/u=2647953258,2919321872&fm=26&gp=0.jpg",
"http://img1.imgtn.bdimg.com/it/u=221171515,1209752772&fm=26&gp=0.jpg"
]
var num = 0;
for(var i = 0; i < arr.length;i++ ){
var oImg = new Image(); //新建一個圖片對象
console.log(oImg);
oImg.onload = function(){
num++; //圖片預加載完成,執行onload裏面的代碼
oBox.style.width = num/arr.length * 100 + "%"; //經過圖片的加載順序,來控制進度條的寬度
}
oImg.src = arr[i]; //給圖片對象添加路徑,注意這條代碼必須加在onload後面
}
}
複製代碼
//節流
// 思路:在規定時間內只觸發一次
function throttle (fn, delay) {
// 利用閉包保存時間
let prev = Date.now()
return function () {
let context = this
let arg = arguments
let now = Date.now()
if (now - prev >= delay) {
fn.apply(context, arg)
prev = Date.now()
}
}
}
function fn () {
console.log('節流')
}
addEventListener('scroll', throttle(fn, 1000))
複製代碼
//防抖
// 思路:在規定時間內未觸發第二次,則執行
function debounce (fn, delay) {
// 利用閉包保存定時器
let timer = null
return function () {
let context = this
let arg = arguments
// 在規定時間內再次觸發會先清除定時器後再重設定時器
clearTimeout(timer)
timer = setTimeout(function () {
fn.apply(context, arg)
}, delay)
}
}
function fn () {
console.log('防抖')
}
addEventListener('scroll', debounce(fn, 1000))
複製代碼
狀況一:純粹的函數調用:這是函數的最一般的用法,屬於全局調用,所以this就表明全局對象
var x = 1;
function test(){
console.log(this.x);
}
test(); // 1 狀況二:做爲對象方法複製代碼
狀況二:做爲對象方法的調用:函數還能夠做爲某個對象的方法調用,這時this就指這個上級對象。
function test(){
console.log(this.x);
}
var obj = {};
obj.x = 1;
obj.m = test;
obj.m();複製代碼
狀況三:做爲構造函數調用:所謂構造函數,就是經過這個函數,能夠生成一個新對象。這時this就指這個新對象。
function test(){
this.x = 1;
}
var obj = new test();
console.log(obj.x); // 1複製代碼
var x = 0;
function test(){
console.log(this.x);
}
var obj = {};
obj.x = 1;
obj.m = test;
obj.m.apply(); // 0 this指的是全局對象
obj.m.apply(obj); // 1 this指的是obj複製代碼
狀況五:隱式綁定:函數的調用是在某個對象上觸發的,即調用位置上存在上下文對象,典型隱士調用:xxx.fn()
function info(){
console.log(this.age);
}
var person = {
age: 20,
info
}
var age = 28;
person.info(); //20;執行的是隱式綁定複製代碼
狀況六:箭頭函數:箭頭函數沒有本身的this,繼承外層上下文綁定的this;
let obj = {
age: 20,
info: function() {
return () => {
console.log(this.age); //this繼承的是外層上下文綁定的this
}
}
}
let person = {age: 28};
let info = obj.info();
info(); //20
let info2 = obj.info.call(person);
info2(); //28複製代碼
function compreObj(obj1, obj2) {
var flag = true;
function compre(obj1, obj2) {
if (Object.keys(obj1).length != Object.keys(obj2).length) {
flag = false;
} else {
for (let x in obj1) {
if (obj2.hasOwnProperty(x)) {
if (obj1[x] !== obj2[x]) {
compre(obj1[x], obj2[x]);
}
} else {
flag = false;
}
}
}
if (flag === false) {
return false;
} else {
return true;
}
}
return compre(obj1, obj2)
}
console.log(compreObj(對象1, 對象2));複製代碼
//不使用事件捕獲
window.onload = function(){
let oBox = document.getElementById("box");
oBox.onclick = function(){
alert(1); //不觸發
}
oBox.onclick = function(){
alert(2); //觸發
}
}
//使用事件捕獲
window.onload = function(){
oBox.addEventListener("click",function(){
alert(1); //觸發
})
oBox.addEventListener("click",function(){
alert(2); //觸發
})
}複製代碼
當爲事件捕獲(useCapture:true)時,先執行body的事件,再執行div的事件
當爲事件冒泡(useCapture:false)時,先執行div的事件,再執行body的事件
var arr = [99,88,66,77];
for(let i in arr){
console.log(i); //0,1,2,3
}
for(let i of arr){
consoel.log(i); //99,88,66,77
}複製代碼
var obj = {name:"Bob",age:25};
for(var i in obj){
console.log(i) // name age
}
for(var i of obj){
console.log(i) //報錯
}複製代碼
function add(x,y){ //普通函數
console.log(x+y);
}
function curryingAdd(x){ //柯里化函數(閉包)
return function(y){
console.log(x+y);
}
}
add(1,2) //3
curryingAdd(1)(2) //3 複製代碼
function add(a,b){
return a+b;
}
function sub(a,b){
return a-b;
}
var a1 = add.apply(sub,[4,2]); //sub調用add的方法
var a2 = sub.apply(add,[4,2]); //add調用sub的方法
var a3 = add.call(sub,4,2); //sub調用add的方法
console.log(a1); //6
console.log(a2); //2
console.log(a3); //6複製代碼
//改變this指向
var obj = {
name:"Bob"
}
var name = "Tom";
function test(){
console.log(this.name);
console.log(this);
}
test(); // Tom Window
test.call(obj); //Bob {name:"Bob"}
//借用別的對象的方法
var Person1 = function(){
this.name = "Bob";
}
var Person2 = function(){
this.getName = function(){
console.log(this.name);
}
Person1.call(this);//this指向Person2,結果至關於給Person2加了name屬性
}
var person = new Person2();
person.getName(); //Bob
//單純的函數調用:
function add(){
alert(1);
}
add.call();複製代碼
查找該元素首次出現的位置和最後出現的位置下標是否相同,同時判斷新數組中是否不存在該元素,若是都知足則添加進新數組中去。
var arr = [1,2,45,44,45,2,89,1,1,2,1,2,44];
Array.prototype.unique = function(){
var arr = this;
var box = [];
for(var str of arr){
if(arr.indexOf(str) != arr.lastIndexOf(str) && box.indexOf(str) == -1){
box.push(str);
}
}
return box;
}
console.log(arr.unique());複製代碼
var arr = [1,2,[3,4,[5,6,[7,8,[9,10]]]]];複製代碼
第一種:
function flatten(arr){
var box = [];
arr.map(v => {
if(Array.isArray(v)){
box = box.concat(flatten(v))
}else{
box.push(v);
}
})
return box;
}
console.log(flatten(arr));複製代碼
第二種(不推薦):
function flatten(arr){
return arr.toString().split(",").map(v => {
return Number(v);
})
}
console.log(flatten(arr));複製代碼
第三種:
function flatten(arr){
console.log(arr.join(","))
return arr.join(",").split(",").map(v => {
return parseInt(v);
})
}
console.log(flatten(arr));複製代碼
第四種:
var arr = [1,2,[3,4,[5,6,[7,8,[9,10]]]]];
function flatten(arr){
return arr.reduce((result,item) => {
console.log(result,item)
return result.concat(Array.isArray(item) ? flatten(item) : item);
},[]);
}
console.log(flatten(arr)); 複製代碼
第五種:
console.log([].concat(...arr));
function flatten(arr){
while(arr.some(item => Array.isArray(item))){
arr = [].concat(...arr);
}
return arr;
}
console.log(flatten(arr)); 複製代碼
var str = "10000000000";複製代碼
第一種:把數字轉換成字符串後,打散爲數組,再從末尾開始,逐個把數組中的元素插入到新數組(result)的開頭。 每插入一個元素,counter就計一次數(加1),當counter爲3的倍數時,就插入一個逗號,可是要注意開頭(i爲0時)不須要逗號。最後經過調用新數組的join方法得出結果。
String.prototype.toThousands = function(){
var num = this;
var result = [ ], counter = 0;
num = (num || 0).toString().split('');
for (var i = num.length - 1; i >= 0; i--) {
counter++;
result.unshift(num[i]);
if (!(counter % 3) && i != 0) { result.unshift(','); }
}
return result.join('');
}
console.log(str.toThousands());複製代碼
第二種:經過正則表達式循環匹配末尾的三個數字,每匹配一次,就把逗號和匹配到的內容插入到結果字符串的開頭, 而後把匹配目標(num)賦值爲還沒匹配的內(RegExp.leftContext)。 若是數字的位數是3的倍數時,最後一次匹配到的內容確定是三個數字,可是最前面的三個數字前不須要加逗號;若是數字的位數不是3的倍數,那num變量最後確定會剩下1到2個數字,循環事後,要把剩餘的數字插入到結果字符串的開頭。
function toThousands(num) {
var num = (num || 0).toString(), re = /\d{3}$/, result = '';
while ( re.test(num) ) {
result = RegExp.lastMatch + result;
if (num !== RegExp.lastMatch) {
result = ',' + result;
num = RegExp.leftContext;
} else {
num = '';
break;
}
}
if (num) { result = num + result; }
return result;
}
console.log(toThousands(str)); 複製代碼
第三種:第二種的改良版
function toThousands(num) {
var num = (num || 0).toString(), result = '';
while (num.length > 3) {
result = ',' + num.slice(-3) + result;
num = num.slice(0, num.length - 3);
}
if (num) { result = num + result; }
return result;
}
console.log(toThousands(str)); 複製代碼
第四種:懶人版
function toThousands(num) {
return (num || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');
}
console.log(toThousands(str));複製代碼
const fn = new Promise(function(resolve,reject){
axios.get(url).then(res => {
resolve(res);
}).catch(err => {
reject(err);
})
}).then((res) => {
console.log(res);
}).catch((err) => {
console.log(err);
})複製代碼
var p1 = Promise.resolve(1),
p2 = Promise.reject(2),
p3 = Promise.resolve(3);
Promise.all([p1, p2, p3]).then((res)=>{
//then方法不會被執行
console.log(results);
}).catch((err)=>{
//catch方法將會被執行,輸出結果爲:2
console.log(err);
});複製代碼
let p1 = new Promise((resolve)=>{
setTimeout(()=>{
console.log('1s') //1s後輸出
resolve(1)
},1000)
})
let p10 = new Promise((resolve)=>{
setTimeout(()=>{
console.log('10s') //10s後輸出
resolve(10) //不傳遞
},10000)
})
let p5 = new Promise((resolve)=>{
setTimeout(()=>{
console.log('5s') //5s後輸出
resolve(5) //不傳遞
},5000)
})
Promise.race([p1, p10, p5]).then((res)=>{
console.log(res); // 最後輸出
})
//結果:
1s
1
5s
10s複製代碼
// 定義AMD規範的模塊
define([function() {
return 模塊
})
//私有成員
define(['module1', 'module2'], function(m1, m2) {
let x = 1;
function add() {
x += 1;
return x;
}
return { add };
})複製代碼
第三種:CMD:CMD 是 SeaJS 在推廣過程當中對模塊定義的規範化產出。AMD 推崇依賴前置,CMD 推崇依賴就近。CMD集成了CommonJS和AMD的的特色,支持同步和異步加載模塊。CMD加載完某個依賴模塊後並不執行,只是下載而已,在全部依賴模塊加載完成後進入主邏輯,遇到require語句的時候才執行對應的模塊,這樣模塊的執行順序和書寫順序是徹底一致的。所以,在CMD中require函數同步加載模塊時沒有HTTP請求過程。
define(function(require, exports, module) {
// 同步加載模塊
var a = require('./a');
a.doSomething();
// 異步加載一個模塊,在加載完成時,執行回調
require.async(['./b'], function(b) {
b.doSomething();
});
// 對外暴露成員
exports.doSomething = function() {};
});
// 使用模塊
seajs.use('path');複製代碼
第四種:module:ES6的模塊化已經不是規範了,而是JS語言的特性。隨着ES6的推出,AMD和CMD也隨之成爲了歷史。ES6模塊與模塊化規範相比,有兩大特色:
//react種運用的就是ES6的模塊化
var module1 = value1;
var module2 = value2;
export {module1,module2} //導出模塊
import {module1,module2} from "模塊路徑/模塊名" //引入模塊複製代碼
function _new(){
let target = {}; //建立的新對象
let [constructor,...args] = [...arguments];
//執行[[原型]]鏈接,target是constructor的實例
target.__proto__ = constructor.prototype;
//執行構造函數,將屬性或方法添加到建立的空對象上
let result = constructor.prototype;
if(result && (typeof (result) == "object" || typeof (result) == "function")){
//若是構造函數執行的結構返回的是一個對象,那麼返回這個對象
return result;
}
//若是構造函數返回的不是一個對象,返回建立的對象
return target;
}複製代碼
call函數
// 思路:將要改變this指向的方法掛到目標this上執行並返回
Function.prototype.mycall = function (context) {
if (typeof this !== 'function') {
throw new TypeError('not funciton')
}
context = context || window
context.fn = this
let arg = [...arguments].slice(1)
let result = context.fn(...arg)
delete context.fn
return result
}複製代碼
apply函數
// 思路:將要改變this指向的方法掛到目標this上執行並返回
Function.prototype.myapply = function (context) {
if (typeof this !== 'function') {
throw new TypeError('not funciton')
}
context = context || window
context.fn = this
let result
if (arguments[1]) {
result = context.fn(...arguments[1])
} else {
result = context.fn()
}
delete context.fn
return result
}複製代碼
bind函數
// 思路:相似call,但返回的是函數
Function.prototype.mybind = function (context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
let _this = this
let arg = [...arguments].slice(1)
return function F() {
// 處理函數使用new的狀況
if (this instanceof F) {
return new _this(...arg, ...arguments)
} else {
return _this.apply(context, arg.concat(...arguments))
}
}
}複製代碼
方法一:數組的 toString 接口默認調用數組的 join 方法,從新 join 方法
let a = [1,2,3];
a.join = a.shift;
console.log(a == 1 && a == 2 && a == 3) //true複製代碼
方法二:利用數據劫持(Proxy/Object.definedProperty)
let i = 1;
let a = new Proxy({},{
i:1,
get:function(){
return () => this.i++
}
});
console.log(a == 1 && a == 2 && a == 3);複製代碼