Giter Club home page Giter Club logo

qixman.github.io's People

Contributors

qixman avatar

Stargazers

 avatar

Watchers

 avatar

qixman.github.io's Issues

【JavaScript Basis】编写个获取数据类型的Fn

Javascript中的数据类型

Javascript中有6中数据类型。

其中5种是简单类型:
boolean, number, string, undefined, null

还有1种复杂类型 object

其实我觉得把 null 归为 Object 类型会更容易理解。因为 typeof 对于 null 的返回值是 object,这是一个让初学者很容易懵逼混淆的点。而 null 意为空指针,没有引用,跟 Object 的引用归为一类也能说的过去。

更为细致的划分

对于复杂类型 object,有更为细致的划分,它包含了函数 function,数组 array, 空指针 null,正则表达式 regexp.

typeof

Javascript_中有一个关键字,为_typeof,输入 data,返回一个字符串,显示的是_data type_.
但是它能返回的类型比较粗枝大叶,对于 object 中的具体类型,没有很详尽。
例如

typeof null; // "object"
typeof []; //"object"
typeof /\b/;// "object"

显然这满足不了你,在工作场景里,检测数据类型是不是array还是很常见的。
当然常用的解决办法是使用 instanceof.

instanceof

instanceof 需要两个参数,一前一后,前者是待检测数据,后者是类型构造函数,返回一个boolean,表示前者是否是后者的实例。

利用这个关键字,也可以达到一些检测数据类型的目的。例如在上面一段提到的typeof不能很好检测的array类型。可以用instanceof 来检测

[1,2,3] instanceof Array;// true

不过这样检测也是太双标了,还得 typeof 和 instanceof 结合着种。

不如自己写个util fn,一步到位。

一步到位的类型检测

这里的关键在于 obj 的 toString方法,这个方法会返回具体类型,然后我们根据这个类型,使用正则处理一下,就可得出想要结果。

需要注意的是只有 obj 的 toString 可以实现这个效果,所以数据如果是别的类型,需要 call 一下这个 obj 的 toString,而不能直接使用自身所带有的 toString.

//key point is the toString method of Object.
const type = data => {
  return typeof data != "object" ?
         typeof data             :
         {}.toString.call(data).match(/\w+/g).pop().toLowerCase();
}

//test cases
const assert = require('assert');
describe("type", () => {
  it("should get right type", () => {
    assert.equal("null", type(null));
    assert.equal("undefined", type(undefined));
    assert.equal("boolean", type(false));
    assert.equal("number", type(1));
    assert.equal("function", type(type));
    assert.equal("array", type([]));
    assert.equal("object", type({}));
    assert.equal("regexp", type(/^$/));
  });
});

提升工作效率的工具栏

Pocket

想读、没时间读的内容随手放进去。
加tag归类便于查找。

Goole Calender

可用作提醒工具,把要做的事儿加在时间点上。
可用作记录工具,将每天每刻所做的事,大概记录下来,便于回顾浏览。

ShadowSocks

VPN,没有它很多工具都无法使用。
速度相对其他VPN很稳定。
不贵。

ProcessOn

思维导图制作工具。(不只思维导图,图种很多。)
在线。

动漫单拉一拉

看着就想吃

中华小当家

赛车

头文字D

体育运动

灌篮高手 (√)
乒乓 (√)

偏女生向

犬夜叉
乱马二分之一

背景设定新奇大胆

进击的巨人
寄生兽

ES6 新手学习记录档

ES6 新手学习记录档

let const

let

在ES5中,通过var声明的变量,作用域是通过function划分的,在function内声明的变量,在函数外无法使用,但是在块(例如if、for等)之外,仍然是有效的。

if(true) { var a = 1 }
console.log(a)//1

但是对于ES6中的let、const两个关键词来说,区别于原来的var,形成block scope(块级作用域)。块内声明的变量,块外无效

if(true) { let a = 1 }
console.log(a)//ReferenceError

ES5时代函数级作用域引发的一个问题场景,就是在循环赋值的时候。

var funcs = []
for(var i=0;i<10;i++){
    funcs.push(function(){
        console.log(i)
    })
}

funcs.forEach(function(func){
    func()
})
//运行结果是10个10,而不是预期的0,1,2,3...
开发人员通常用js闭包的特性来搞定这个问题
var funcs = []
for(var i=0;i<10;i++){
    (function(idx){
        funcs.push(function(){
            console.log(idx)
        })
    })(i)
}

funcs.forEach(function(func){
    func()
})
//运行结果为0,1,2,3,4....

ES6中增加了块级作用域的概念,就可以使用let取代var,便不需多写闭包这种hack了。
值得一提的是,let不存在变量提升,但是它有个暂时性死区的概念。

console.log(a)//undefined
console.log(b)//报错,没有提升
var a = 1
let b = 1

所谓暂时性死区,就是一个区域,从变量所在的作用域开头,到变量使用let声明之间的区域,在这个区域内,对这个变量的一切操作都会报错。

const

const是个常量的概念,一些配置信息或者不变更的量都可以用const来定义,防止被胡乱篡改。

const a = 1
a = 2 //报错

这里需要注意的是,const声明的变量,如果是引用类型,那么这个变量的内容是可以改变的。const能保证的,只是指针的不变。

const a = {}
a = {}//报错

a.name = "xiaoming"//没问题
Array Function

箭头函数,这个语法的出现,让函数的写法更加简单了,尤其是写匿名函数的时候,例如:

//es5
let arr = [1,2,3].map(function(x){
    return x+1
})

//es6
let arr2 = [1,2,3].map((x)=>(x+1))
//小括号可以不加,但是为了防止挖坑,一般加上。
//函数体内容较多的时候,用{}

值得注意的是箭头函数中的this,是定义时所在的对象,而不是使用时所在的对象。
所以可以告别var self = this这种hack了。

var bob = {
    _name: "Bob",
    _friends: [],
    printFriends() {
        this._friends.forEach(f => consol.log(this._name + " knows " + f));
    }
}

Class

ES6 class 与 ES5 prototype 两种思路实现oop的对比

这是一个语法糖,开发人员写oop‘可能’更便捷了,而且代码可读性有所提高,更重要的是,这个改变很可能是对将来一些新功能的拓展做准备。

在es5里,我们实现一个类,依靠的是function以及prototype这两个东西,function可以配合关键词new创建实例,prototype可以让对象继承其他对象。

//es5
function Person(name) {
    this.name = name;
    Person.count++
}
//一些其他方法
Person.prototype.sayNotGood = function(){
    console.log('hey,' + this.name+",you are " + Person.getCount() +" I've created,heyheyhey")
}

//静态方法
Person.getCount = function(){
    return Person.count + "th"
}

//静态属性
Person.count = 0

let xiaoming = new Person('xiaoming')
xiaoming.sayNotGood()//hey,xiaoming,you are 1th I"ve created,heyheyhey

而在ES6中,引进了class关键词,创建类变得方便,对有java等oop语言开发基础的同志来说,尤其如此

   //es6
   class Person{
       //构造函数
       constructor(name){
           this.name = name
           Person.count++
       }

       //其他方法
       sayNotGood(){
           console.log(`hey,${this.name},you are ${Person.getCount()} I ve created,heyheyhey`)
       }

       //静态方法
       static getCount(){
           return Person.count + "th"
       }
   }

   //静态属性这个语法在es7才能实现,目前state-0
   Person.count = 0

   let xiaoming = new Person('xiaoming')
xiaoming.sayNotGood()//hey,xiaoming,you are 1th I've created,heyheyhey

也说过了,class只是一个语法糖,它本质上,还是一个function

typeof Person//function

但是还是有一些性质上的差别,比如class与function没有提升

let p = new Person()
class Person{}
//这得报错

关于继承(没有填的坑)

Template string

模板字符串,有了这个新特性,+号拼接字符串的时代就过去了,变成了往字符串里面插变量。

let name = "xiaoming"
`hey,${name}` // "hey,xiaoming"
parameter

default parameter

默认参数在别的编程语言中比较常见了,在没有对参数赋值的时候,使用默认值。在es5中,常用||也就是‘或’来实现相关逻辑。

//es5
function foo(bar){
    var a = bar ||'baz'
    console.log(a)
}

foo()//'baz'
foo('shit')//'shit'

在es6里,这个逻辑可由默认参数来完成

//es6
let foo = (a='baz')=>{
       console.log(a)
   }

foo()//'baz'
foo('shit')//'shit'
rest parameter

这个语法允许把一坨参数作为数组调用。
在es5中,由于arguments是arraylike类型,是个object,因此无法使用forEach、map等好用的array method。以往的处理方式是hack一下,利用[].slice.call(arguments,0)切割一下。

function addSome(){
       var paras,sum
       paras = [].slice.call(arguments,0)
       sum = paras.reduce(function(sum,next){
           return sum + next
       })
       console.log(sum)
   }

   addSome(1,2,3)//6

这个语法的出现,可以彻底取消这个hack,直接操作原生数组

let addSome = (...nums)=>(nums.reduce((sum,next)=>(sum+next)))
addSome(1,2,3)//6

顺便说一点,ES6中对Array也添加了一些新的好用的api,其中Array.from也是一个能将arrylike转化成原生array的利器

Array.from(arguments)
//等价于
[].slice.call(arguments,0)

反过来,形参很多,实参出入一个数组,也是可以自动解析的,关键语法在于...的使用

let add3num = (x,y,z) => (x+y+z) 
let arr = [1,2,3]
console.log(add3num(...arr))//6

因此,可以这么理解,...这个符号的作用,就是将一个数组array,打散成一堆元素。

//如何拼接两个数组?
//在es5中,我们得用concat
[1,2,3].concat([1,2,3])//[1,2,3,1,2,3]

//那么有了...操作符,我们可以将其打散,直接组装
[...[1,2,3],...[1,2,3]]//[1,2,3,1,2,3]

For…of

for…of跟for…in不同很多,都说for-in遍历的时候可能不按顺序来,因此不适合遍历数组,最好用来遍历属性,不过我写了一些test倒是没实现…

二者最根本的区别,不是别的:for-of遍历值,for-in遍历索引

let arr = [1,2,3]
   for(let i in arr){
       console.log(i)//0,1,2
   }

   for(let i of arr){
       console.log(i)//1,2,3
   }

for-of本质上遍历的不是一个数组,而是数组自动调用生成的迭代器iterator,因此凡是拥有迭代属性的东西,for-of都能遍历,比如generator,比如iterator

//for-of搞generator
function *fibonacci(stop){
    let [a,b] = [0,1]
    for(let i=1; i<=stop; i++){
        [a,b] = [b,a+b]
        yield a
    }
}

for(let i of fibonacci(5)){
    console.log(i)//1,1,2,3,5
}

//for-of搞iterator
let arr = [1,2,3]
    iter = arr[Symbol.iterator]()
for(let i of iter){
    console.log(i)//1,2,3
}

ES6 新手学习记录档

ES6 新手学习记录档

[!TOC]

let const

let

在ES5中,通过var声明的变量,作用域是通过function划分的,在function内声明的变量,在函数外无法使用,但是在块(例如if、for等)之外,仍然是有效的。

if(true) { var a = 1 }
console.log(a)//1

但是对于ES6中的let、const两个关键词来说,区别于原来的var,形成block scope(块级作用域)。块内声明的变量,块外无效

if(true) { let a = 1 }
console.log(a)//ReferenceError

ES5时代函数级作用域引发的一个问题场景,就是在循环赋值的时候。

var funcs = []
for(var i=0;i<10;i++){
    funcs.push(function(){
        console.log(i)
    })
}

funcs.forEach(function(func){
    func()
})
//运行结果是10个10,而不是预期的0,1,2,3...
开发人员通常用js闭包的特性来搞定这个问题
var funcs = []
for(var i=0;i<10;i++){
    (function(idx){
        funcs.push(function(){
            console.log(idx)
        })
    })(i)
}

funcs.forEach(function(func){
    func()
})
//运行结果为0,1,2,3,4....

ES6中增加了块级作用域的概念,就可以使用let取代var,便不需多写闭包这种hack了。
值得一提的是,let不存在变量提升,但是它有个暂时性死区的概念。

console.log(a)//undefined
console.log(b)//报错,没有提升
var a = 1
let b = 1

所谓暂时性死区,就是一个区域,从变量所在的作用域开头,到变量使用let声明之间的区域,在这个区域内,对这个变量的一切操作都会报错。

const

const是个常量的概念,一些配置信息或者不变更的量都可以用const来定义,防止被胡乱篡改。

const a = 1
a = 2 //报错

这里需要注意的是,const声明的变量,如果是引用类型,那么这个变量的内容是可以改变的。const能保证的,只是指针的不变。

const a = {}
a = {}//报错

a.name = "xiaoming"//没问题
Array Function

箭头函数,这个语法的出现,让函数的写法更加简单了,尤其是写匿名函数的时候,例如:

//es5
let arr = [1,2,3].map(function(x){
    return x+1
})

//es6
let arr2 = [1,2,3].map((x)=>(x+1))
//小括号可以不加,但是为了防止挖坑,一般加上。
//函数体内容较多的时候,用{}

值得注意的是箭头函数中的this,是定义时所在的对象,而不是使用时所在的对象。
所以可以告别var self = this这种hack了。

var bob = {
    _name: "Bob",
    _friends: [],
    printFriends() {
        this._friends.forEach(f => consol.log(this._name + " knows " + f));
    }
}

Class

ES6 class 与 ES5 prototype 两种思路实现oop的对比

这是一个语法糖,开发人员写oop‘可能’更便捷了,而且代码可读性有所提高,更重要的是,这个改变很可能是对将来一些新功能的拓展做准备。

在es5里,我们实现一个类,依靠的是function以及prototype这两个东西,function可以配合关键词new创建实例,prototype可以让对象继承其他对象。

//es5
function Person(name) {
    this.name = name;
    Person.count++
}
//一些其他方法
Person.prototype.sayNotGood = function(){
    console.log('hey,' + this.name+",you are " + Person.getCount() +" I've created,heyheyhey")
}

//静态方法
Person.getCount = function(){
    return Person.count + "th"
}

//静态属性
Person.count = 0

let xiaoming = new Person('xiaoming')
xiaoming.sayNotGood()//hey,xiaoming,you are 1th I"ve created,heyheyhey

而在ES6中,引进了class关键词,创建类变得方便,对有java等oop语言开发基础的同志来说,尤其如此

   //es6
   class Person{
       //构造函数
       constructor(name){
           this.name = name
           Person.count++
       }

       //其他方法
       sayNotGood(){
           console.log(`hey,${this.name},you are ${Person.getCount()} I ve created,heyheyhey`)
       }

       //静态方法
       static getCount(){
           return Person.count + "th"
       }
   }

   //静态属性这个语法在es7才能实现,目前state-0
   Person.count = 0

   let xiaoming = new Person('xiaoming')
xiaoming.sayNotGood()//hey,xiaoming,you are 1th I've created,heyheyhey

也说过了,class只是一个语法糖,它本质上,还是一个function

typeof Person//function

但是还是有一些性质上的差别,比如class与function没有提升

let p = new Person()
class Person{}
//这得报错

关于继承(没有填的坑)

Template string

模板字符串,有了这个新特性,+号拼接字符串的时代就过去了,变成了往字符串里面插变量。

let name = "xiaoming"
`hey,${name}` // "hey,xiaoming"
parameter

default parameter

默认参数在别的编程语言中比较常见了,在没有对参数赋值的时候,使用默认值。在es5中,常用||也就是‘或’来实现相关逻辑。

//es5
function foo(bar){
    var a = bar ||'baz'
    console.log(a)
}

foo()//'baz'
foo('shit')//'shit'

在es6里,这个逻辑可由默认参数来完成

//es6
let foo = (a='baz')=>{
       console.log(a)
   }

foo()//'baz'
foo('shit')//'shit'
rest parameter

这个语法允许把一坨参数作为数组调用。
在es5中,由于arguments是arraylike类型,是个object,因此无法使用forEach、map等好用的array method。以往的处理方式是hack一下,利用[].slice.call(arguments,0)切割一下。

function addSome(){
       var paras,sum
       paras = [].slice.call(arguments,0)
       sum = paras.reduce(function(sum,next){
           return sum + next
       })
       console.log(sum)
   }

   addSome(1,2,3)//6

这个语法的出现,可以彻底取消这个hack,直接操作原生数组

let addSome = (...nums)=>(nums.reduce((sum,next)=>(sum+next)))
addSome(1,2,3)//6

顺便说一点,ES6中对Array也添加了一些新的好用的api,其中Array.from也是一个能将arrylike转化成原生array的利器

Array.from(arguments)
//等价于
[].slice.call(arguments,0)

反过来,形参很多,实参出入一个数组,也是可以自动解析的,关键语法在于...的使用

let add3num = (x,y,z) => (x+y+z) 
let arr = [1,2,3]
console.log(add3num(...arr))//6

For…of

for…of跟for…in不同很多,都说for-in遍历的时候可能不按顺序来,因此不适合遍历数组,最好用来遍历属性,不过我写了一些test倒是没实现…

二者最根本的区别,不是别的:for-of遍历值,for-in遍历索引

let arr = [1,2,3]
   for(let i in arr){
       console.log(i)//0,1,2
   }

   for(let i of arr){
       console.log(i)//1,2,3
   }

for-of本质上遍历的不是一个数组,而是数组自动调用生成的迭代器iterator,因此凡是拥有迭代属性的东西,for-of都能遍历,比如generator,比如iterator

//for-of搞generator
function *fibonacci(stop){
    let [a,b] = [0,1]
    for(let i=1; i<=stop; i++){
        [a,b] = [b,a+b]
        yield a
    }
}

for(let i of fibonacci(5)){
    console.log(i)//1,1,2,3,5
}

//for-of搞iterator
let arr = [1,2,3]
    iter = arr[Symbol.iterator]()
for(let i of iter){
    console.log(i)//1,2,3
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.