其他分享
首页 > 其他分享> > 一些回想~

一些回想~

作者:互联网

想点什么些什么

CSS篇

line-height:2 与line-height:200% 区别

line-height:2 单行文本是自身高度的两倍行高
ling-height:200 单行文本是系统默认字体的200%

继承性
父元素设置line-height:2,父元素的子元素会继承它,子元素的行高是自身高度的两倍。所以父元素跟子元素行高不相同
父元素设置line-height:200%,同样会继承,但是系统默认字体是固定的,所以父元素、子元素的行高是一样的

JS篇

箭头函数 this 的 指向

创建时的this,不是调用时的

闭包

一个函数可以访问内部函数变量

function makeAdder(x) {
  return function(y) {
    return x + y;
  };
}
var add5 = makeAdder(5);
console.log(add5(2));  // 7

解构赋值

var a, b; 
var c = ['啊', '吧' , '哈']
var [a, ...b] = c
console.log(a, b) // 啊, ['吧', '哈']

 var C = {obj:'123', obj1:'321'}
 var {obj, obj1} = C
 console.log(obj,obj1) // 123 321

对象 for in 循环

var obj = {
    a1:'我是第一个',
    a2:'我是第er个',
    a3:'我是第三个',
}

for(item in obj){ // item就是每一项
    console.log(item, obj[item]) // a1 我是第一个 ...
}

手写一个new()

function mynew() {
    var constr = Array.prototype.shift.call(arguments)
    var obj = Object.create(constr.prototype)
    var result = constr.apply(obj,arguments)
    return result instanceof Object ? result : obj 
}
 function Person(name, age) {
     this.name = name
     this.age = age
 }
 const person1 = new Person('new啦啦', 18)
 const person2 = mynew(Person, '自定义new啦啦', 17)
 console.log(person1, person2)

手写promise

function myPromise(constructor){
    let self=this;
    self.status="pending" //定义状态改变前的初始状态
    self.value=undefined;//定义状态为resolved的时候的状态
    self.reason=undefined;//定义状态为rejected的时候的状态
    function resolve(value){
        //两个==="pending",保证了状态的改变是不可逆的
       if(self.status==="pending"){
          self.value=value;
          self.status="resolved";
       }
    }
    function reject(reason){
        //两个==="pending",保证了状态的改变是不可逆的
       if(self.status==="pending"){
          self.reason=reason;
          self.status="rejected";
       }
    }
    //捕获构造异常
    try{
       constructor(resolve,reject);
    }catch(e){
       reject(e);
    }
}
    同时,需要在myPromise的原型上定义链式调用的then方法:
myPromise.prototype.then=function(onFullfilled,onRejected){
   let self=this;
   switch(self.status){
      case "resolved":
        onFullfilled(self.value);
        break;
      case "rejected":
        onRejected(self.reason);
        break;
      default:       
   }
}

测试

var p=new myPromise(function(resolve,reject){resolve(1)});
p.then(function(x){console.log(x)})
//输出1

深拷贝(是拷贝对象各个层级的属性)

简洁深拷贝:JSON.parse(JSON.stringify())

递归深拷贝:

function deepClone(obj){
    let objClone = Array.isArray(obj)?[]:{};
    if(obj && typeof obj==="object"){
        for(key in obj){
            if(obj.hasOwnProperty(key)){
                //判断ojb子元素是否为对象,如果是,递归复制
                if(obj[key]&&typeof obj[key] ==="object"){
                    objClone[key] = deepClone(obj[key]);
                }else{
                    //如果不是,简单复制
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
}    

对象深拷贝注意

使用JSON.parse() JSOM.stringify()的时候当值为undefined、function、symbol 会在转换过程中被忽略

对象Objet.assign() // 浅拷贝!!!

Object.assign({},sources)方法只会拷贝源对象自身的并且可枚举的属性到目标对象(如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后面的源对象的属性将类似地覆盖前面的源对象的属性)。
Object.assign({}, …sources){}定义一个空对象 / Object.assign(target, …sources)也可目标对象,sources源对象(要合并的对象,可多个)

数组深拷贝注意

let [… arr2] = arr // …展开运算符 (数组包含对象||数组时就会失效,是没有把数组里面的对象深拷贝,而是浅拷贝)

let arr2 = arr.concat() // concat(array) 连接两个或多个数组返回新数组 (数组包含对象||数组时就会失效,是没有把数组里面的对象深拷贝,而是浅拷贝)

let arr2 = arr.slice(0) // slice(start,end) 从已有数组选定返回 (数组包含对象||数组时就会失效,是没有把数组里面的对象深拷贝,而是浅拷贝)

原型/原型链

原型

每个函数都有prototype属性(显式原型),这个属性指向函数的原型对象
每个对象(除了null)都有__proto__ 属性(隐式原型),指向该原型
每个原型都有constructor属性,指向该关联的构造函数

对象的原型只是一个引用,指向另一个对象。对象原型之间的嵌套组成了原型链,原型链的做用是维护访问对象属性的查询,肯定访问权限

原型链

拿对象的一个属性,但对象本身没有这个属性,就会去__proto__构造函数的对象中去寻找,如原型也没有就会一直__proto__往原型得原型上找,直到对象的原型对象是null结束寻找。形成链式解构 (原型链)

function Person() {
    this.name ='飒飒';
    this.age = 18
  }
let newperson = new Person()

Person.prototype.sex = '我是男女!'
Person.prototype.age = 87

console.log(newperson.age) // 18
console.log(newperson.sex) // 我是男女,对象本身没有这个属性,__proto__去原型上找,原型没有返回undefined
console.log(Person.prototype) {sex: "你猜猜,我是男女!", age: 87, constructor: ƒ}

Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__

Object.create() 与 Object.setPrototypeOf() 都是设置一个对象的原型对象
区别 在进行俩个原型之间的委托时使用setPrototype更好,Object.create更适和直接对一个无原生原型的对象快速进行委托
Object.create() 凸显重新赋值, obj——> new prototype (直接赋值了新的原型)
Object.setPrototypeOf() obj——> old prototype(本身原来的原型) ——>new prototype

Object.defineProperty()

备注:应当直接在 Object 构造器对象上调用此方法,而不是在任意一个 Object 类型的实例上调用。

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象

Object.defineProperty(obj, prop, descriptor) obj/目标对象 prop/要定义或修改的属性名 descriptor/要定义或修改的属性描述符,返回值:被传递给函数的对象。

let data = {}
let name = '三角龙'
Object.defineProperty(data,'name',{
    get:function(){
        return name
    },
    set:function(newvalue){ // 这里可以的到值得修改
        if( name !== newvalue){
            name = newvalue
        }
        return name
    }
})

Proxy 代理拦截

vat proxy = new Proxy(target, handler)

用es6提供构造函数,生成proxy实例  target表示要拦截的目标对象, handler 参数也是对象,用来你制定的拦截行为(就是你拦截那个对象要干嘛)
    let son = {
        name: '小子',
        age: 16,
        sex: '男'
    }
    let proxy = new Proxy( son, {
        get(target, key) {
            return target[key] 
        },
        <!-- set接受四个参数,1、Target用于接收属性的对象 2、key 要写入的“属性键”(我称为值得名字,可字符串或symbol)3、value 被写入的“属性值”(我称为写入的值)4、receiver:操作发生的对象(通常是代理)-->
        set(target, key, value) {
            // if(key === 'age' && typeof value !=='number') { //这里拦截了age不是number
            //     throw Error('年龄必须事number!')
            // }
            if(key === 'name' && value !=='小子') { //拦截不叫小子的
                console.log('必须叫小子(proxy拦截)')
                throw Error('必须叫小子')
            }
            return Reflect.set(target, key, value);
        }
    })
    proxy.name = '假小子' // 这里就会触发代理拦截set里面我们自己定义判断的语句
    let son = {
        name:'小子',
        age:26,
        sex:'男',
        desc:'这个是老子(grandson他爸爸)'
    }
    // 定义拦截行为
    let validator {
        get: function(obj,key){
            return obj[key]
        }
        set: function(obj,name,value){
            if(name === 'age' && value < 5) {
                console.log('这小屁孩五岁都没有,拦他!!!(proxy拦截)')
                throw Error('必须>五岁再说')
            }
            obj[name] = value
            // 这里还可以赋值给别的对象(给son的对应值进行修改或赋值)
            son[name] = value
        }
    }
    // 定义proxy
    let grandson = new Proxy({}, validator)
    grandson.name = 'son的儿子'
    grandson.age = 2 // 触发set定义的判断

vuex(五个属性)

state moutations actions getters modules

state: 存放值的
getters: 是store的计算属性
moutations: 同步操作,直接修改state的值 
    SET_TOKEN: (state, token) => {
        state.token = token
      },
actions: 异步操作,通过commit用moutations的方法去修改state的值
    commit('SET_TOKEN', res)
modules: 模块化,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

页面使用actions的方法修改state的值:this.$store.dispatch(‘某个模块/方法名’,传参)

页面使用moutations的方法修改state的值:this.$store.commit(“doLogout”);

vue的computed计算属性和wacth侦听器

watch顾名思义,用于监听数据变化,其中可以监听的数据来源有三部分:props、data、computed内的数据;watch提供两个参数(newValue,oldValue),第一个参数是新值,第二个参数旧值;(每次都会触发监听,不会有缓存)

computed用于处理复杂的逻辑运算,主要和methods储存方法来进行区分;methods储存方法,computed储存需要处理的数据值;methods每次都会调用,computed有缓存机制,只有改变时才执行,性能更佳(有缓存,默认去get,有变化才会触发set);

    watch: {
        // wacthvalue这个在data中有定义,有变化就可以监听到做自己想要的处理
       wacthvalue(newvalue,oldvalue){
           console.log(newid,'东西',oldid)
            // 代表在wacth里声明了firstName这个方法之后立即执行handler方法
            immediate: true
       }
     }
  computed:{
      //computedMsg这个没有在data数据中没有定义的,页面直接this.computedMsg使用
    computedMsg:{
        get() { // 来取这里的值,赋值给computedMsg
           return '我是data其他值来赋值或计算给computedMsg' // 可直接返回值
           return this.xx + this.yy //也可以data里面的数据,这里xx,yy 有变化会触发
        },
        set(val) { // computedMsg值变化,这里就触发
          console.log(val,'变化liao')
        }
    }
  }

标签:function,Object,obj,name,对象,回想,原型,一些
来源: https://blog.csdn.net/weixin_44644144/article/details/120222172