美文网首页
前端开发备忘录

前端开发备忘录

作者: 无迹落花 | 来源:发表于2018-05-21 12:01 被阅读61次
  1. js

数组去重的方法

  • 最常用的方式
function filter(args) {
    var arr=[]
    for(let i=0;i<args.length;i++){
        if(arr.indexOf(args[i])==-1){
                arr.push(args[i])
            }   
    }
    return arr
}

var arr1=[1,2,3,2,3,4,4,5]

console.log(filter(arr1))          //  [1,2,3,4,5]
  • 对象键值法去重

function uniq(args){
    var temp={},r=[],val,type

    for(let i=0;i<args.length;i++){
        val=args[i]   //  1,2,3,2,3,4
        type=typeof val
        console.log(temp[val])  //  number
        if(!temp[val]){
            temp[val]=[type]
            r.push(val)
        }else if(temp[val].indexOf(type)<0){
            temp[val].push(type)
            r.push(val)
        }
    }

    return r
}

var arr2=[1,2,3,2,3,4,4,5]

console.log(uniq(arr2))      //    [1,2,3,4,5]

  • es6 Set方法一键去重

var arr=[1,1,2,3,2,4,4,6]

arr=new Set(arr)

console.log([...arr])    //     [1, 2, 3, 4, 6]





js常见的循环与遍历以及不同循环遍历之间的区别

  • for 循环遍历
var arr=[1,1,2,3,2,4,4,6]



for(let i=0;i<arr.length;i++){
    console.log(arr[i]);   
}

//   1,1,2,3,2,4,4,6

//   for循环 需要知道数组的长度
  • forEach循环
//  forEach循环,循环数组中每一个元素并采取操作, 没有返回值, 可以不用知道数组长度

var arr=["Andy",30,180,"male"]

arr.forEach((value,key)=>{
    console.log(value)  //   Andy    30    180   male
    console.log(key)    //    0      1      2     3
})

//  forEach循环不能循环遍历对象 

console.log(Array.prototype.hasOwnProperty("forEach"))  //  true

console.log(Object.prototype.hasOwnProperty("forEach"))  //  false

//  可知, forEach方法时定义在 Array原型链上的。 所以对象不能 forEach
  • map 循环
  //   map函数,遍历数组每个元素,并回调操作,需要返回值,返回值组成新的数组,原数组不变
  var arr=[1,1,2,3,4,4,5]

  arr.map((value,key)=>{
      console.log(value)  //   1 1 2 3 4 4 5
      console.log(key)    //   0 1 2 3 4 5 6
  })


//  map循环里面存在一个回调函数,所以可以实现改变数组内容,参照下面的代码,原数组不变。

var arr=[1,1,2,3,4,4,5]

var tt=arr.map((i)=>{
    i=i+"world";
    return i
})

console.log(tt)  //  ["1world", "1world", "2world", "3world", "4world", "4world", "5world"]

console.log(arr)  //  [1, 1, 2, 3, 4, 4, 5]
  • filter函数
     //   filter函数, 过滤通过条件的元素组成一个新数组, 原数组不变

  var arr=["J.R.Smith",30,"kidding","naive",33,12,0,null,undefined,1,8,7]



  var tt=arr.filter(i=>{
      return typeof i=="number"
  })

  console.log(arr);    //  ["J.R.Smith", 30, "kidding", "naive", 33, 12, 0, null, undefined, 1, 8, 7]

  console.log(tt)     //   [30, 33, 12, 0, 1, 8, 7]

//  filter方法提供了一个可以过滤数组的途径。
  • some函数
    //  some函数,遍历数组中是否有符合条件的元素,返回Boolean值

var arr=["J.R.Smith",30,"kidding","naive",33,12,0,null,undefined,1,8,7]


var tt=arr.some(i=>{
    return typeof i=="number"
})

console.log(arr);    //  ["J.R.Smith", 30, "kidding", "naive", 33, 12, 0, null, undefined, 1, 8, 7]

console.log(tt)     //   true
  • every函数
// every函数, 遍历数组中是否每个元素都符合条件, 返回Boolean值

var arr=["J.R.Smith",30,"kidding","naive",33,12,0,null,undefined,1,8,7]


var tt=arr.every(i=>{
    return typeof i=="number"
})

console.log(arr);    //  ["J.R.Smith", 30, "kidding", "naive", 33, 12, 0, null, undefined, 1, 8, 7]

console.log(tt)     //   false
  • for...in遍历

    for...in语句以任意顺序遍历一个对象的可枚举属性。对于每个不同的属性,语句都会被执行。


//   `for...in` 循环只遍历可枚举属性。

var obj={
    name:"Andy",
    age:30,
    weight:180,
    sex:'male'
}


for(let i in obj){
    console.log(i,obj[i])  //  name Andy
                           //  age 30
                           //  weight 180
                           //  sex male
}




下面代码展示了,当对象的enumerable属性被设置为false时候,不能被for...in 遍历

var obj={
    name:"Andy",
    age:30,
    weight:180,
    sex:'male'
}

Object.defineProperty(obj,"age",{
    enumerable:false,
    configurable:false,
    writable:false,
    value:"static"
})


for(let i in obj){
    console.log(i,obj[i])  
}
enumerable

上图可以看到,for ...in 遍历中,age这个属性没了。


cookie localStorage 和sessionStorage三者之间的区别




ES6 一共有 5 种方法可以遍历对象的属性。

for...in



Object.keys

getOwnPropertyNames(obj)

getOwnPropertySymbols(obj)

Reflect.ownKeys(obj)

以上的 5 种方法遍历对象的键名,都遵守同样的属性遍历的次序规则。

首先遍历所有数值键,按照数值升序排列。
其次遍历所有字符串键,按照加入时间升序排列。
最后遍历所有 Symbol 键,按照加入时间升序排列。


Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 })  
['2', '10', 'b', 'a', Symbol()]
   



ES5的继承
es5
//  es5 的继承

//  定义父类
function Person(name){
    this.name=name
}

// 定义父类的可继承属性与方法
Person.prototype={
    name:this.name,
    showName:function(){
        console.log(this.name)
    }
}


//  定义继承函数
function Student(name,grade){
    Person.call(this,name)
    this.grade=grade
}

Student.prototype=Object.create(Person.prototype)

Student.prototype.showGrade=function(){
    console.log(this.grade)
}

// 绑定construct之前,Student.prototype.constructor与Student是不等的
console.log(Student.prototype.constructor==Student) // false

//  打印一下Student.prototype.constructor
console.log(Student.prototype.constructor)   //   ƒ Object() { [native code] }

// 绑定construct
Student.prototype.constructor=Student

var s1=new Student("小华","高三")
var p1=new Person("小明")

s1.showName()   //  小华
s1.showGrade()  //  高三

p1.showName()  // 小明

ES5中这种最简单的继承,实质上就是将子类的原型设置为父类的实例。

需要经过
    1.定义祖先
    2.定义祖先可继承的变量/方法
    3.定义继承的类(构造函数),并在类中调用组件的方法 call和apply方法
    4.使用 prototyoe定义继承关系
    5.重新将constructor指向自己

ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。

ES6的继承
es6
//  es6的继承

//定义类

class Person {
    // constructor方法,就是构造方法
    // 如果没有定义构造方法,js会自动为其添加
    //  constructor方法默认返回实例对象(即this),完全可以指定返回另外一个对象 例如: return Object.create({name:"John",age:31})
    //  new一个类的实例的时候,会立即调用constructor方法
    constructor(name){
        this.name=name
        this.showName=function(){
            console.log(this.name)
        }
    }

    //  下面的这个sayHello方法它是不可枚举的,这一点与es5不同
    //  需要注意的是,下面的这个sayHello方法不是定义在类Person上的,也不是定义在类的实例对象上的,而是定义在类Person的原型上的
    //  Person.hasOwnProperty('sayHello')  // false
    //  p1.hasOwnProperty('sayHello')  // false
    //  Person.prototype.hasOwnProperty('sayHello')  // true
    //  p1.__proto__hasOwnProperty('sayHello')  // true
    sayHello(){
            console.log('hello')
    }
}

var p1=new Person("xiao8")

console.log(Object.keys(p1))    //  ["name", "showName"]  看到没有,sayHello不可枚举,constructor内部定义的变量与方法可枚举


//构造函数的prototype属性,在 ES6 的“类”上面继续存在。   
//事实上,类的所有方法都定义在类的prototype属性上面。
console.log(Person===Person.prototype.constructor)   //  true





//实现继承

class Student extends Person{
    constructor(name,grade){
        //调用父类的构造函数,用来新建父类的this对象
        //super作为函数调用时,返回的是子类B的实例,super内部的this指向B
        //super相当于 A.prototype.constructor.call(this)
        //super作为函数只能用在constructor中
        super(name)
        this.grade=grade
    }

    toString() {
        //super作为对象使用时,指向父类的原型对象。
        //在静态方法中指向父类
        //定义在父类实例上的方法是没办法用的
        return this.name + ' ' +super.sayHello();//调用父类的方法
    }
}


//可以使用getPrototypeOf方法来获取父类
console.log(Object.getPrototypeOf(Student)===Person)   // true

//这里和es5不一样
//对象有属性__proto__,指向该对象的构造函数的原型对象。
//方法除了有属性__proto__,还有属性prototype,prototype指向该方法的原型对象。

var p1 = new Person("Andy");
var s2 = new Student("小华",'三年级');

console.log(p1.__proto__ === p1.__proto__)// true
console.log(s2.__proto__.__proto__ === p1.__proto__) // true



http 状态码解读

相关文章

网友评论

      本文标题:前端开发备忘录

      本文链接:https://www.haomeiwen.com/subject/smsfjftx.html