JavaScript零零散散

  • 一些優(yōu)雅的寫法
    邏輯運算符

    if (a == 1) {
      b()
    }
    // 可以寫成
    a == 1 && b()
    
    if (conected) {
      login();
    }
    // 可以寫成
    conected && login();
    
    
    // 如果一些屬性或函數(shù)存在于一個對象中,你也可以這樣做檢測,如下面的代碼所示:
    user && user.login();
    

    初始化變量

    var a = obj || {}
    var name = name || "Oliver Queen";
    
  • 類型轉換

    ("""" + ) > String() > .toString() > new String()
    
  • 多字符串拼接,先壓數(shù)組,后join

  • 盡量使用直接量,區(qū)別在于引擎直接解釋和調用具體數(shù)據(jù)類型內(nèi)部構造器。

  • 字符串操作盡量不用循環(huán),而使用正則表達式,區(qū)別在于JavaScript引擎運行邏輯與調用C語言API。

  • 同理,三元比較返回大小與Math.min相比,應選擇后者。

  • 自定義高級對象和Date、RegExp對象在構造時都會消耗大量時間。如果可以復用,應采用緩存的方式。

  • JavaScript中各種高度、寬度:辨析詳解:

Name Code
網(wǎng)頁可見區(qū)域寬 document.body.clientWidth
網(wǎng)頁可見區(qū)域寬 document.body.clientWidth
網(wǎng)頁可見區(qū)域高 document.body.clientHeight
網(wǎng)頁可見區(qū)域寬 (包括邊線的寬) document.body.offsetWidth
網(wǎng)頁可見區(qū)域高 (包括邊線的寬) document.body.offsetHeight
網(wǎng)頁正文全文寬 document.body.scrollWidth
網(wǎng)頁正文全文高 document.body.scrollHeight
網(wǎng)頁被卷去的高 document.body.scrollTop
網(wǎng)頁被卷去的左 document.body.scrollLeft
網(wǎng)頁正文部分上 window.screenTop
網(wǎng)頁正文部分左 window.screenLeft
屏幕分辨率的高 window.screen.height
屏幕分辨率的寬 window.screen.width
屏幕可用工作區(qū)高度 window.screen.availHeight
屏幕可用工作區(qū)寬度 window.screen.availWidth
如圖
  • !!variable做檢測,只要變量的值為:false0、null、" "、undefined或者NaN都將返回的是false,反之返回的是true。

  • 使用+variableStringDate直接轉為數(shù)字。

  • 數(shù)組原生函數(shù)方式獲取元素:

    var array = [1,2,3,4,5,6];
    console.log(array.slice(1,2));  // [1,2]
    console.log(array.slice(3));    // [3,4,5,6]
    console.log(array.slice(-1));   // [6]
    console.log(array.slice(-2));   // [5,6]
    console.log(array.slice(-3));   // [4,5,6]
    
  • 數(shù)組截斷可以直接指定數(shù)組length屬性等于想要的長度即可。

  • 字符串替換所有:

    var string = "john john";
    console.log(string.replace(/hn/, "ana"));  // "joana john"
    console.log(string.replace(/hn/g, "ana")); // "joana joana"
    
  • 合并數(shù)組:

    var array1 = [1,2,3];
    var array2 = [4,5,6];
    console.log(array1.push.apply(array1, array2)); // [1,2,3,4,5,6]; 原理是拼起來。
    console.log(array1.concat(array2)); // [1,2,3,4,5,6]; 原理是生成一個新的數(shù)組。
    
  • NodeList to Array

    var elements = document.querySelectorAll("p"); // NodeList
    var arrayElements = [].slice.call(elements); // Now the NodeList is an array
    var arrayElements = Array.from(elements); // This is another way of converting NodeList to Array
    
  • 數(shù)組元素的洗牌

    var list = [1,2,3];
    console.log(list.sort(() => Math.random() - 0.5)); // [2,1,3]
    
  • JavaScript獲取對象的屬性的三種方法

    for...in: 該方法依次訪問一個對象及其原型鏈中所有可枚舉的屬性
    Object.keys(O): 該方法返回一個數(shù)組,它包含了對象O自身的所有可枚舉屬性的名稱
    Object.getOwnPropertyNames(O):該方法返回一個數(shù)組,它包含了對象O所有擁有的屬性(包括不可枚舉)的名稱
    
  • JavaScript中substring()、substr()、slice()的區(qū)別

    var stringValue = "hello world";
    
Code Comments
stringValue.slice(3) "lo world"
stringValue.substring(3) "lo world"
stringValue.substr(3) "lo world"
stringValue.slice(3,7) "lo w"
stringValue.substring(3,7) "lo w"
stringValue.substr(3,7) "lo worl"
stringValue.slice(-3) "rld" 從后往前數(shù)3個開始
stringValue.substring(-3) "hello world" 為負,默認從0開始
stringValue.substr(-3) "rld"
stringValue.slice(3,-4) "lo w" 下標從3開始到-4(從后往前數(shù)4個)
stringValue.substring(3,-4) "hel"
stringValue.substr(3,-4) "" 長度為負,默認不顯示
  • ~~ 運算符用在JavaScript中有按位取反的作用,~即是取反兩次,而位運算的操作值要求是整數(shù),其結果也是整數(shù),所以經(jīng)過位運算的都會自動變成整數(shù),可以巧妙的去掉小數(shù)部分,類似于parseInt,比如:

    let a = 1.23;
    let b = -1.23;
    console.log(~~a); // 1
    console.log(~~b); // -1
    
  • || 運算符
    巧妙的使用 || 運算符我們可以給變量設置默認值,比如:

    let c = 1;
    let d = c || 2; // 如果c的值為true則取存在的值,否則為2
    console.log(d); // 1
    
  • ...運算符
    ...運算符是ES6中用于解構數(shù)組的方法,可以用于快速獲取數(shù)組的參數(shù),比如:

    let [num1, ...nums] = [1, 2, 3];
    console.log(num1); // 1
    console.log(nums); // [2, 3]
    
  • new Set()
    可能有人知道ES6中提供了新的數(shù)據(jù)結構 Set,但是能夠靈活運用的人或許不多。利用Set數(shù)據(jù)結構我們能夠輕松的去重一個數(shù)組,比如:

    let arr = [1, 2, 2, 3];
    let set = new Set(arr);
    let newArr = Array.from(set); // Array.from方法可以將 Set 結構轉為數(shù)組。
    console.log(newArr); // [1, 2, 3]
    
  • Object.assign()
    Object.assign()也是ES6中提供的對象的擴展方法,其可以用于對象的合并拷貝,比如:

    let obj1 = {a: 1};
    let obj2 = {b: 2};
    let obj3 = Object.assign({}, obj1, obj2);
    console.log(obj3); // {a: 1, b: 2}
    
  • 注入

    evilCode.replace(/.+/,eval)//
    
  • JavaScript中訪問屬性和訪問變量的標識符查找規(guī)則
    標識符查找

    • 訪問屬性,查找的是原型鏈;
    • 訪問變量,查找的是作用域鏈;

    當通過屬性調用的方式調用對象的方法時,該對象只會成this的值;不會成為它的方法(即:對象中屬性值是函數(shù)的屬性)的作用域鏈中的作用域對象,不過可以通過with操作符使對象成為它的方法的作用域鏈中的作用域對象。

     gby;        //結果:報錯:ReferenceError: Can't find variable: gby;
     window.gby; //結果:undefined
    

    訪問變量時是通過搜索作用域鏈來查找變量的,而訪問屬性是通過搜索原型鏈來查找屬性的,因為這兩種訪問方式的搜索方式不一樣,所以導致了結果不一樣;

  • 以下來自內(nèi)容部分來自《淺談JavaScript、ES5、ES6》:

    1. ES6支持動態(tài)聲明對象屬性

      const obj = {
        [ 'prop_' + (() => 42)() ]: 42 
      }
      console.log(obj); // {prop_42: 42}
      
    2. 賦值解構

      let singer = {
        first: "Bob",
        last: "Dylan"
      };
      let {
        first: f,
        last: l
      } = singer; // 相當于 f = "Bob", l = "Dylan"   
      let [all, year, month, day] = /^(dddd)-(dd)-(dd)$/.exec("2015-10-25"); // v8 不支持?
      let [x, y] = [1, 2, 3]; // x = 1, y = 2
      let [, , x, y] = [1, 2, 3]; // x = 3, y = undefined
      
    3. 函數(shù)參數(shù) - 默認值、參數(shù)打包、 數(shù)組展開(Default 、Rest 、Spread)

      // Default
      function findArtist(name = 'lu', age = '26') {
        console.log(name, age);
      }
      findArtist(...['li', ]); // li 26
      // Rest
      function f(x, ...y) {
        // y is an Array
        return x * y.length;
      }
      console.log(f(3, "hello", true)); //  6
      // Spread  
      function f2(x, y, z) {
        return x + y + z;
      }
      // Pass each elem of array as argument 
      console.log(f2(...[1, 2, 3])) // 6
      
    4. Iterators(迭代器)+ for..of。迭代器有個next方法,調用會:
      (1).返回迭代對象的一個元素:{ done: false, value: elem }
      (2).如果已到迭代對象的末端:{ done: true, value: retVal }

    5. Class

      class Artist {
        constructor(name) {
          this.name = name;
        }
        perform() {
          return this.name + " performs ";
        }
      }
      class Singer extends Artist {
        constructor(name, song) {
          super(name);
          this.song = song;
        }
        perform() {
          return super.perform() + "[" + this.song + "]";
        }
      }
      let james = new Singer("Etta James", "At last");
      console.log(james instanceof Artist); // true   
      console.log(james instanceof Singer); // true   
      console.log(james.perform()); // "Etta James performs [At last]"
      
    6. Modules
      ES6的內(nèi)置模塊功能借鑒了CommonJS和AMD各自的優(yōu)點:
      (1).具有CommonJS的精簡語法、唯一導出出口(single exports)和循環(huán)依賴(cyclic dependencies)的特點。
      (2).類似AMD,支持異步加載和可配置的模塊加載

      // lib/math.js   
      export function sum(x, y) {
        return x + y;
      }
      export var pi = 3.141593;
      
      // app.js   
      import * as math from "lib/math";
      alert("2π = " + math.sum(math.pi, math.pi));
      
      // otherApp.js   
      import {
        sum,
        pi
      } from "lib/math";
      alert("2π = " + sum(pi, pi));
      
      // Dynamic loading – ‘System’ is default loader   
      // Module Loaders:
        System.import('lib/math').then(function (m) {
          alert("2π = " + m.sum(m.pi, m.pi));
        });
      // Directly manipulate module cache   
      System.get('jquery');
      System.set('jquery', Module({
        $: $
      }));
      // WARNING: not yet finalized
      
    7. Map + Set + WeakMap + WeakSet
      四種集合類型,WeakMap、WeakSet作為屬性鍵的對象如果沒有別的變量在引用它們,則會被回收釋放掉。

      // Sets   
      var s = new Set();
      s.add("hello").add("goodbye").add("hello");
      s.size === 2;
      s.has("hello") === true;
      
      // Maps   
      var m = new Map();
      m.set("hello", 42);
      m.set(s, 34);
      m.get(s) == 34;
      
      //WeakMap   
      var wm = new WeakMap();
      wm.set(s, {
        extra: 42
      });
      wm.size === undefined
      
      
      // Weak Sets   
      var ws = new WeakSet();
      ws.add({
        data: 42
      });
      //Because the added object has no other references, it will not be held in the set
      
    8. Math + Number + String + Array + Object APIs 一些新的API

      Number.EPSILON
      Number.isInteger(Infinity) // false      
      Number.isNaN("NaN") // false      
      Math.acosh(3) // 1.762747174039086      
      Math.hypot(3, 4) // 5      
      Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2      
      "abcde".includes("cd") // true      
      "abc".repeat(3) // "abcabcabc"      
      Array.from(document.querySelectorAll('*')) // Returns a real Array      
      Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior      
      [0, 0, 0].fill(7, 1) // [0,7,7]     
      [1, 2, 3].find(x => x == 3) // 3      
      [1, 2, 3].findIndex(x => x == 2) // 1      
      [1, 2, 3, 4, 5].copyWithin(3, 0) // [1, 2, 3, 1, 2]      
      ["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"]
      ["a", "b", "c"].keys() // iterator 0, 1, 2      
      ["a", "b", "c"].values() // iterator "a", "b", "c"      
      Object.assign(Point, {
        origin: new Point(0, 0)
      }) plain
      
    9. Proxies 使用代理(Proxy)監(jiān)聽對象的操作,然后可以做一些相應事情。
      可監(jiān)聽的操作: get、set、hasdeleteProperty、apply、constructgetOwnPropertyDescriptor、defineProperty、getPrototypeOf、setPrototypeOfenumerate、ownKeys、preventExtensions、isExtensible。

      var target = {};
      var handler = {
        get: function (receiver, name) {
          return `Hello, ${name}!`;
        }
      };
      var p = new Proxy(target, handler);
      p.world === 'Hello, world!'; // true
      
    10. Symbol是一種基本類型。Symbol 通過調用symbol函數(shù)產(chǎn)生,它接收一個可選的名字參數(shù),該函數(shù)返回的symbol是唯一的。

      var key = Symbol("key");
      var key2 = Symbol("key");
      key == key2 // false
      
    11. Promises是處理異步操作的對象,使用了 Promise 對象之后可以用一種鏈式調用的方式來組織代碼,讓代碼更加直觀。

      function fakeAjax(url) {
        return new Promise(function (resolve, reject) {
          // setTimeouts are for effect, typically we would handle XHR 
          if (!url) {
            return setTimeout(reject, 1000);
          }
          return setTimeout(resolve, 1000);
        });
      }
      // no url, promise rejected 
      fakeAjax().then(function () {
        console.log('success');
      }, function () {
        console.log('fail');
      });
      
    12. 替換字符串最后一個匹配,參考
      str.replace(/(.*)and/, '$1but');// 正則表達時,貪婪模式,.*會一直匹配到最后一個

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容