JavaScript之技巧与陷阱 - 起点终站

我们应该感谢相遇,无论结局是喜是悲....
JavaScript之技巧与陷阱
  • 首页 > IT技术
  • 作者:起点终站
  • 2017年6月8日 15:37 星期四
  • 浏览:18496
  • 字号:
  • 评论:2
  • 这里有一些JavaScript初学者应该知道的技巧和陷阱。 如果你已经是一个专家,那就随意阅读。

    你尝试过给一组数字排序吗?

    Javascript的sort()方法默认用来给数字排序

    所以[1,2,5,10].sort()将会输出[1, 10, 2, 5].

    要正确的对数组进行排序的话,你可以使用[1,2,5,10].sort((a, b) => a — b)

    只要你一开始就知道这个坑的话,解决起来就很容易.

    new Date()很奇妙

    new Date()可以接受:

    • 没有参数就返回当前时间

    • 一个参数x就返回当前时间1970年1月1日,+ x毫秒,Unix的人知道为什么

    • new Date(1,1,1)返回1901年,2月1日.因为你知道,第一个1意思是1900年后的1年,第二个1是这一年的第二个月(因此二月) —— 二月的正确索引在索引表中为1 ,第三个1显然是这个月的第一天,所以是1 —— 因为有时索引确实从1开始。

    • 哦,还有new Date(2016年,1,1)不会从2016年追加到1900年。它仅仅表示2016年。

    Replace不替代

    我觉得这是件好事,因为我不喜欢函数去改变他输入的值,你应该也知道replace只会替换他第一个匹配:

    let s = "bob"
    const replaced = s.replace('b', 'l')
    replaced === "lob" // first match only
    s === "bob" // original string is remained unchanged

    如果你想替换所有,你可以使用带有/ g的正则表达式:

    "bob".replace(/b/g, 'l') === 'lol' // replace all occurences

    当心比较

    // These are ok
    'abc' === 'abc' // true
    1 === 1         // true
    // These are not
    [1,2,3] === [1,2,3] // false
    {a: 1} === {a: 1}   // false
    {} === {}           // false

    理由:[1,2,3][1,2,3]是两个单独的数组。它们恰好包含相同的值,但是它们有不同的引用,不能用全等===比较

    数组不是原始数据类型

    typeof {} === 'object'  // true
    typeof 'a' === 'string' // true
    typeof 1 === number     // true
    // But....
    typeof [] === 'object'  // true

    想知道你的是不是数组,  你仍然可以使用Array.isArray(myVar)或者[] instanceof Array来判断

    闭包

    这是一道有名的JavaScript面试题:

    const Greeters = []
    for (var i = 0 ; i < 10 ; i++) {
      Greeters.push(function () { return console.log(i) })
    }
    
    Greeters[0]() // 10
    Greeters[1]() // 10
    Greeters[2]() // 10

    你是不是期望它输出0,1,2 ...? 你知道为什么它却没有输出吗? 你会如何修改它?

    我们提出两个可能的解决方案:

    使用let 来替换var。 立马解决。

    "在letvar之间的差异是作用域,var i的作用域是最近的函数块,而let的作用域是最近的封闭块,封闭块可以小于函数块。(如果在任何块之外使用的话,letvar它们都是全局的)

    其他方法:使用 bind:

    Greeters.push(console.log.bind(null, i))

    其实有很多种方法去解决,这是我推荐的2种方法.

    聊聊绑定

    你认为这个将会输出什么?

    class Foo {
      constructor (name) {
        this.name = name
      }
      greet () {
        console.log('hello, this is ', this.name)
      }
      someThingAsync () {
        return Promise.resolve()
      }
      asyncGreet () {
        this.someThingAsync()
        .then(this.greet)
      }
    }
    new Foo('dog').asyncGreet()

    理由:greet没有在正确的上下文运行,同样,是有很多方法可以解决。

    我个人比较喜欢

    asyncGreet () {
      this.someThingAsync()
      .then(this.greet.bind(this))
    }

    这样做可以确保greet可以被作为上下文的实例调用。

    如果你不希望greet在实例上下文外运行,你还可以在类的constructor函数中绑定它.

    class Foo {
      constructor (name) {
        this.name = name
        this.greet = this.greet.bind(this)
      }
    }

    你还应该知道箭头函数(=>)可以被用于保留上下文。它也可以这样使用:

    asyncGreet () {
      this.someThingAsync()
      .then(() => {
        this.greet()
      })
    }

      您阅读这篇文章共花了:  
    本文作者:起点终站      文章标题: JavaScript之技巧与陷阱
    本文地址:https://blog.hellozwh.com/?post=287
    版权声明:若无注明,本文皆为“起点终站”原创,转载请保留文章出处。
    • blogger
    nzhuang2019-08-28 23:09
    这几天也在看有关闭包的知识,第一次去接触,经过一晚折磨,好,我知道什么是闭包了。隔天,又看到闭包题,马什么梅?翻开笔记,打开百度各种查资料,好,这次我彻底明白了!!今天再看到闭包,。。。什么梅?o(╥﹏╥)o
    起点终站 没错,我就是那个帅逼站长2019-08-29 10:11
    @nzhuang:哈哈
    返回顶部| 首页| 手气不错| 网站地图| sitemap| 装逼生成器| 站长介绍|

    Copyright © 2016-2019 起点终站 闽ICP备16011094号-1