js补充2

typeof和instanceof的区别使用
typeof [] 和 type {} // 结果都是object
[] instanceof Array // 这样返回true ,代表是数组
把数组变成键值的形式
let a = ['小明','小红']

console.log(JSON.stringify(Object.entries(a),null,2));
/* [
  [       
    "0",  
    "小明"
  ],
  [
    "1",
    "小红"
  ]
] */

自己实现简单深拷贝
// 深拷贝就是赋值不会影响到原来的对象
// 思路就是使用递归,尽量形成值传递而不是引用关系
let user = {
  name:'小明',
  title:{
    name:'标题'
  },
  arr:[1,2,3]
}

function copy(obj){
  // 这里是为了保存本来就是数组的形式
  let res = obj instanceof Array ? [] : {}

  for (const [k,v] of Object.entries(obj)) {
    res[k] =  typeof v === "object"?copy(v):v
    console.log(res);
  }
  return res 
}
let user2 = copy(user)

/* { name: '标题' }
[ 1, 2, 3 ]
{ name: '小明', title: { name: '标题' }, arr: [ 1, 2, 3 ] }
PS D:\vue练习项目\js练习> node index.js
{ name: '小明' }
{ name: '标题' }
{ name: '小明', title: { name: '标题' } }
[ 1 ]
[ 1, 2 ]
[ 1, 2, 3 ]
{ name: '小明', title: { name: '标题' }, arr: [ 1, 2, 3 ] } */

使用构造函数的抽象,保护参数和值不被随意改变

function user(name,age){

  // 把传进来的参数,再封装一次
  let data = {name}
  // 不抽象的时候是
  this.age = age
  // this.name = name


  // 函数抽象写法
  let info = function (){
    return data.age > 10 ? '傻逼':'大傻逼'  
  }
  // 不抽象写法
  this.show = function (){
    console.log(data.name + info());
  }
}

let aa = new user('小明',20)

// 修改里面值
aa.name = '小红'
aa.age = 5 

aa.info = function (){
  return '我是大傻逼'
}

aa.show()  // 小明大傻逼 原因,name属性抽象了,无法修改,然后修改age的值,拿到了三目后面的值

Object.entries()的使用

let arr = {name:'dashabi',age:101}

for (const [key,value] of Object.entries(arr)) {
  console.log(key,value);
}

保护对象不可以添加新的属性

let obj = {name:'大傻逼'}
Object.preventExtensions(obj) // 控制对象不可以添加新得属性
console.log(Object.isExtensible(obj)); // false 判断对象是否被控制不可以添加新的属性

保护对象不可以添加,删除属性

let obj = {name:'大傻逼'}
// 保护属性不被删除添加,和添加新的特性 但还可以修改属性值 也叫封闭状态
  Object.seal(obj)
  obj.age = 18
  obj.name = '小煞笔'
  delete name
  console.log(obj); //   obj.name = '小煞笔'
// 判断是否是封闭状态
console.log(Object.isSealed(obj)); // true

对象全封闭(不可以删除,修改,添加)

Object.freeze(obj)
obj.name = '小煞笔'
console.log(obj); // { name: '大傻逼' }

console.log(Object.isFrozen(obj)); // true 判断是否全封闭

访问器得使用

// 访问器的使用
// 平常我们去拿到一个对象的属性的时候,可以随意的拿,可以随意的修改,但如果想要在这个过程中加一些限制,那么这些限制就是访问器
  const user = {
    data:{name:'大傻逼',age:18},
    set age(value){ // 修改值得时候,给值加个控制
      value>=100?console.log('不行'):this.data.age = value 
    },
    get age(){
      return this.data.age
    }  
  }

user.age = 102
console.log(user); // 不行 { data: { name: '大傻逼', age: 18 }, age: [Setter] }
console.log(user.age); // 18

console.log(user.age); // 如果没有get age set age方法会undefined

访问器的级别高

// 访问器的使用
let user = {
  data:{name:'大傻逼',age:18},
  set name(value){
  //  console.log(value + '小煞笔');
  //  this.name = value + '小煞笔' // 这里改了this.name 也会触发set name方法,然后无线循环
  this.data.name = value + '小煞笔'  // 但是把name放到data里面进行设置就不会循环
  }
}
user.name = '三傻逼'
console.log(user); // 三傻逼小煞笔 说明访问器的级别高于直接设置name

结合symbol属性使用访问器

// 其实使用data把属性包起来,使用user.data.name 还是可以直接修改name的值
// 那么有什么办法可以限制它这样的修改呢
let DATA = Symbol() // symbol是单一类型,是绝对不会重复
let user = {
    [DATA]:{name:'大傻逼',age:18},
    set name(value){
    this[DATA].name = value + '小煞笔'  
    }
}
console.log(user); // { name: [Setter], [Symbol()]: { name: '大傻逼', age: 18 } }
console.log(user[Symbol()].name); // 会报错,因为每一个symbol类型都是不一样的

构造函数中使用访问器

// 构造函数中使用访问器
function User(name,age){
  let data = {name,age}
  // 这里使用访问器
  Object.defineProperties(this,{
    name:{
      get(){
        // 可以在这里设置验证
        return data.name
      },
      set(value){
        // 可以在这里设置验证
        data.name = value
      }
    }
  })
}

let aa = new User('小明',18)
aa.name = '小红'  // 这是直接设置值

console.log(aa.name); // 这里通过访问器获取的

对象代理

// 访问器是对对象的属性进行性处理,代理是对对象进行处理
// 代理的正常使用
let aa = {name:'小明'}
let prory = new Proxy(aa,{              // prory 就用来代理aa的对象 别人想要访问aa对象的时候,是通过prory来访问的
  get(obj,property){
    return obj[property] + '我是大傻逼'  // obj是上面代理的aa对象,property是别人访问对象的时候访问的属性
  },
  set(obj,property,value){
    obj[property] = value+'大傻逼吗你'   // obj是上面代理的aa对象,property是别人访问对象的时候访问的属性,value是访问对象修改对象的值
  }
})

console.log(prory.name);  // 小明我是大傻逼
prory.name = '小红'

函数代理

// 代理的正常使用
let aa = {name:'小明'}
let prory = new Proxy(aa,{              // prory 就用来代理aa的对象 别人想要访问aa对象的时候,是通过prory来访问的
  get(obj,property){
    return obj[property] + '我是大傻逼'  // obj是上面代理的aa对象,property是别人访问对象的时候访问的属性
  },
  set(obj,property,value){
    obj[property] = value+'大傻逼吗你'   // obj是上面代理的aa对象,property是别人访问对象的时候访问的属性,value是访问对象修改对象的值
  }
})

console.log(prory.name);  // 小明我是大傻逼
prory.name = '小红'
console.log(prory.name);  // 小红大傻逼吗你我是大傻逼

代理对函数进行控制

// 代理还可以对函数进行控制
function bb(num){
  console.log('进来');
  console.log(num);  // 100
  return num
}
let prory1 = new Proxy(bb,{
  apply(func,obj,args){
    console.log(func);    // func代表代理的对象
    console.log(obj);     // obj相当于指向的对象,就算谁执行的就是这里
    console.log(args);    // 因为是apply,所以是数组传参的   [100]
    func.apply(obj,args)
  }
})
prory1.apply({},[100])
// [Function: bb]
// {}
// [ 100 ]
// 进来
// 100

对数组继续代理

// 对数组进行代理
let arr = [
  {name:'小明',age:18},
  {name:'小绿',age:20},
  {name:'小宝',age:25}
]
let prory = new Proxy(arr,{
  get(arr,key){
    return arr[key].name
  }
})
console.log(prory[1]);   // 小绿

使用代理实现双向绑定

<body>
  <input type="text" v-model= "title">
  <input type="text" v-model= "title">
  <h1 v-bind="title"></h1>
</body>
<script>
  function aa(){
    let prory = new Proxy({},{
      get(obj,properry){
        console.log(obj);
      },
      set(obj,properry,value){
        document.querySelectorAll(`[v-model="${properry}"]`).forEach(item=>{item.value = value})    // 通过数据某个属性,拿到这个input,然后把值改掉
        document.querySelectorAll(`[v-bind="${properry}"]`).forEach(item=>{item.innerHTML = value}) // 通过数据某个属性,拿到这个input,然后把值改掉
      },
    })
    this.init = function(){
      let eles = document.querySelectorAll('[v-model]') 
      eles.forEach(item=>{
        console.log(item);
        item.addEventListener('keyup',function(){             // 首先绑定一个键盘起来的事件
          prory[this.getAttribute('v-model')] = this.value    // 然后通过代理,现在代理着上面的input,把修改的值赋值给prory,代理着上面两个input
        })
      })
    }
  }
  new aa().init()
</script>

使用代理工厂来做input验证规则

<style>
  .aa{
    border: solid 10px red;
  }
</style>
<script>
  // 定义一个验证类
  class Validate{
    max(value,len){
      return value.length<len
    }
    min(value,len){
      return value.length>len
    }
    isNumber(value){
      return /^\d+$/.test(value)
    }
  }
  // 定义一个代理工厂
  function ProxyFa(target){
      return new Proxy(target,{
        get(target,key){
          return target[key]
        },
        set(target,key,el){
          let rule = el.getAttribute('rule')  // 通过传进来过来的input值,然后拿到验证的规则
          console.log(rule);                  // 点击第一个input的时候  max:12,min:3
          let validate = new  Validate()
          let state = rule.split(',').every(rule=>{       // [max:12,min:3]   every方法就是,里面的都为true,才返回true
            let info = rule.split(':')
            return validate[info[0]](el.value,info[1])    // 
          })        
          console.log(state);   // 当遍历every里面的所有item,并且所有item都符合规则的时候便返回true
          el.classList[state?'remove':'add']('aa')   // 设置样式,可以使用classList.add 或者classList.remove
        }
      })
  }

  // 使用代理工厂
  let proxy = ProxyFa( document.querySelectorAll('[validate]'))
  proxy.forEach((item,i)=>{
    item.addEventListener('keyup',function(){
       proxy[i] = this                         // 这里主要是用来触发set事件 此时set事件的value是input本身
    })
  })

</script>

JSON格式的使用,作为各开发语言沟通的桥梁

JSON.stringify

let aa = {
  name:'xiaming',
  age:10
}
// 转换成JSON格式 , JSON格式的类型是字符串
// 第二个参数是数组的时候,数组内的值代表转换成json格式的属性
// 第三个参数代表返回的json格式前面带有几个空格
console.log(JSON.stringify(aa,['name'],2));
// {
//   "name": "xiaming"
// }

// 这个方法还可以对数组进行JSON格式的转换
let bb = ['小明','大傻逼']
console.log(JSON.stringify(bb,null,2));
// [
//   "小明",
//   "大傻逼"
// ]

自定义返回toJSON的使用

// 自定义返回 toJSON
let cc = {
  name:'xiaming',
  age:10,
  tea:{
    name1:'小红'
  },
  toJSON:function(){
    return {
      name:this.tea.name1,
      age:this.age
    }
  }
}
console.log(JSON.stringify(cc,null,2));
// {
//   "name": "小红",
//   "age": 10
// }

JSON.parse

// JSON.parse 的使用
let dd = {
  name:'xiaming',
  age:10,
  tea:{
    name1:'小红'
  }
}
let json = JSON.stringify(dd,null,2)

// JSON.parse的使用
let obj = JSON.parse(json,(key,value)=>{      
  if (key === 'name') {
    value = '小明'+value
  }
  return value                 // { name: '小明xiaming', age: 10, tea: { name1: '小红' } }
})
console.log(obj);

你可能感兴趣的:(JS)