1.Object.freeze()

  方法用于冻结一个对象,即将对象设置为不可扩展、将对象的所有自有的属性和方法(包括Symbol值的属性和方法)配置为不可配置,不可写。

  Object.freeze(obj)

  返回值是已冻结的对象。

  这个操作不会影响从原型对象继承来的属性和方法,即只影响自有的属性和方法,一旦对象被冻结,其自身的所有属性都不可能以任何方式被修改。

2.深度选择器 >>> 与 /deep/

.fuck >>> .weui-cells {
// ...
}

有些想sass、less、scss之类的预处理器无法正确解析可以使用 /deep/ 取而代之,/deep/是 >>> 的别名

vue组件中,在style设置为scoped的时候,里面在写样式对子组件是不生效的,如果想让某些样式对子组件都生效,可以使用/deep/深度选择器

.wrap{
/deep/ .class{
font-size: 12px;// 对所有子组件生效
/deep/ .class2{};// 没有必要写多层deep,父类有deep,子类自动也会深度选择,在firfox里会失效
}
}

3.在循环中使用break、continue和return语句之间的区别

  break:此语句将退出循环执行循环后面的语句。如果break语句包含在嵌套循环里,它只跳出最里面的循环。

  continue:程序运行到此语句时,不再执行循环体中continue后面的语句,而是跳到下一个循环入口执行下一个循环

  return:表示被调函数返回到主调函数继续执行,返回时可附带一个返回值,由return后面的参数指定。return之后,函数就结束了,后面的语句不再执行

4.JS中数组函数的总结

  push():像数组的末尾添加一个或多个元素,并返回新的长度

  pop():删除数组的最后一个元素,数组的长度减1,并且返回删除元素的值(当数组为空的时候,不改变数组,并返回undefined)

  unshift():向数组的头部添加一个或多个元素,返回新的长度

  shift():删除并返回数组的第一个元素

  reverse():倒叙

  sort():对数组元素进行排序(默认按照ASCLL),可以传递一个函数,自定义排序规则

  concat():连接两个或多个数组

  split(): 把字符串转换成数组

  join():把所有的元素放进一个字符串,通过指定的分隔符进行分割

  splice(index, howmany, item1, ..., itemX):可以做 删除/插入/替换 操作(替换就是先删除再添加,响应式的)

    index 必需,规定添加删除项目的位置,使用负数可从数组结尾处规定位置

    howmany 必需,要删除的项目数量,如果设置为 0,则不会删除项目

    item, ..., itemX 可选,像数组添加的新的元素

  substr(start, length)

  substring(start, end)

  slice(start, end):截取。从某个已有的数组返回选定的元素,不包含 end 元素(没有 end 参数,就到数组的结尾)

  indexOf(x, start):返回某个指定字符串再字符串中首次出现的位置

    x 必需,规定检索的字符串

    start 可选,规定在字符串中开始检索的位置,合法值是 0 至 arr.length - 1,如果省略该值,则从字符串的首字符开始检索

  lastIndexOf(x, fromindex):指定字符串值,最后出现的位置,在一个字符串中的指定位置从后向前搜索

    x 必需,规定检索的字符串

    fromindex 可选,规定字符串开始检索的位置,合法值 0 至 arr.length -1 ,若省略,则将从字符串最后一个字符处开始检索

  toString():转换为字符串

  valueOf():返回数组的原始值,返回数组本身

  includes(x, start):判断字符串或数组中是否包含指定的字符串,返回Boolean

    x 必需,要查找的数据

    start 可选,设置从那个位置开始查找,默认0

  find(function(currentValue, index, arr), thisValue):返回通过判断的数组的第一个元素的值,不会对空数组执行

    currentValue 必需,当前元素

    index 可选,当前元素的索引值

    arr 可选,当前数组对象

   thisValue 可选,传递给函数的值一般用 this 值

  instanceof:检测是否是数组

    arr instanceof Array;// 返回Boolean

  Array.isArray(obj):判断obj是否是数组,返回Boolean

 JS中数组高阶函数的理解 some()、every()、fiflter()、map()、forEach()、reduce()

  some((item, index, arr)=>{}):返回一个Boolean,判断是否有元素符合func中的条件

      item 必选,index 可选,索引值。arr 当前数组,可选

      不会对空数组进行检测,不会改变原始数组

    const arr = [1,2,3,4,5];
    arr.some(item=>item>2);// 返回true

  every((item,index,arr)=>{}):返回一个Boolean,判断每个元素是否符合func中的条件

       item必选,index 可选,索引值。arr当前数组,可选

      不会对空数组进行检测,不会改变原始数组

    const arr = [2,3,4,5,6];
    arr.every(item=>item>2);// 返回false

  filter((item,index,arr)=>{}):返回一个符合func条件的元素数组(es6)

       item必选,index 可选,索引值。arr当前数组,可选

      filter() 不会对空数组进行检测。不会改变原始数组

    let arr = [2,3,4,5];
    arr.filter(item=>item>2);// 返回 [3,4,5]

  map((item, index, arr)=>{}):返回一个新的array,数组元素由每一次调用函数产生结果组成

      item必选,index 可选,索引值。arr当前数组,可选

      map() 不会对空数组进行检测,不会改变原始数组

    const arr = [1,2,3,4,5];
    arr.map(item=>item*2);// 返回 [2,4,6,8,10]

  forEach((item, index, arr)=>{}):调用数组的每个元素,并将元素传递给回调函数(没有返回值,将数组遍历)

      item 参数是必须的,当前元素。index 可选,当前索引值。arr 可选,当前元素所属的数组对象

      forEach() 对于空数组是不会执行回调函数的

    const a = [1, 22, 333]
    a.forEach((item, index, arr)=>{
      console.log(item);// 1 22 333
      console.log(index);// 0 1 2
      console.log(arr);// arr 为遍历的数组
    })    

  reduce():接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值

    可以作为一个高阶函数,用于函数的 compose ,对于空数组是不会执行回调函数的

    let arr = [{count: 1, price: 2},{count: 3, price: 3}, {count: 2, price: 2}];
    arr.reduce(function(total, currentValue, index, arr){}, initialValue)// initialValue 可选,传递给函数的初始值
    // 参数 total 必需,初始值,或者计算结束后的返回值。currentValue必需,当前元素。index 可选,索引。arr 可选,数组对象
    let sum = arr.reduce(function(total, item){
      return total + item.count * item.price;
    },0)// 最终返回15

5.jquery获取radio, checkbox, checked 的值的时候不能使用attr

  要使用prop进行获取和设置值

  获取选中的属性

    $("#id").prop('checked');

    $("#id").get(0).checked

    document.getElementById("#id").checked

    $("#id").is(":checked")

  设置选中

    $("#id").prop('checked', true);

    $("#id").get(0).checked = true;

    document.getElementById("#id").checked = true;

6.多个异步请求成功后在执行后续方法

  1--jquery 中 $.when() 方法

  $.when($.ajax(), $.ajax()).done(function(a1, a2){
    // a1是第一个异步返回的数据,a2是第二个异步返回的数据
  }).file(function(){
    alert('file')
  })
// 以上代码是先执行两个操作$.ajax,如果都成功了,就运行done(),如果有一个或都失败了就执行fail()

  $.when(deferreds)

    Deferred 类型 一个或多个延迟对象,或者普通的js对象

  2--使用promise中的all()方法实现

  Promise.all([
new Promise(resolve => {
setTimeout(() => {
resolve('100')
}, 1000)
}),
new Promise(resolve => {
setTimeout(() => {
resolve('200')
}, 1000)
})
]).then(data => {
console.log('5555')
})

7.word-wrap: break-word;

  允许长单词换行到下一行

8.数组引用的时候,直接改变数据会影响原数据的值

   let a = [1,2,3,4,5];

  let b = a;

  b[2] = 22;// 此时a数组也是[1,2,22,4,5]

  要想不改变原始数据的值,

  let c = JSON.parse(JSON.stringify(a))

  c[2] = 2222;// 此时改变的只是c中的值    

9.js浅拷贝与深拷贝的区别和实现

  区别:假设 B 复制了 A ,当修改 A 时,看 B 是否会发生改变,如果 B 变了,说明是浅拷贝,若 B 没有改变,那就是深拷贝

  1.如果是基本数据类型,名字和值都会储存在栈内存中

    let a = 1;
    let b = a;// 栈内存会开辟一个新的内存空间,此时 a 和 b 都是相互独立的
    b=2;//此时a还是1

  以上算不上深拷贝,因为深拷贝本身只针对比较复杂的 object 类型数据

  2.如果是引用类型,名字存在栈内存中,值存在堆的内存中,但是栈内存会提供一个引用的地址指向堆内存中的值

    let a  = [1,2,3]
    let b = a;// 此时进行拷贝,其实复制的是 a 的引用地址,而并非堆里面的值
    a[1] = 222;// 在修改数组时,由于 a 与 b 指向的时同一个地址,所以 b 也跟着相应的改变,这就是浅拷贝

  3.实现浅拷贝的方法

    1.for...in 只循环第一层

    // 只复制第一层的浅拷贝
    function simpleCopy(obj1) {
      var obj2 = Array.isArray(obj1) ? [] : {};
      for (let i in obj1) {
        obj2[i] = obj1[i];
      }
      return obj2;
    }
    var obj1 = {
      a: 1,
      b: 2,
      c: {
        d: 3
      }
    }
    var obj2 = simpleCopy(obj1);
    obj2.a = 3;
    obj2.c.d = 4;
    alert(obj1.a); // 1
    alert(obj2.a); // 3
    alert(obj1.c.d); // 4
    alert(obj2.c.d); // 4

    2.Object.assign方法

    var obj = {
    a: 1,
    b: 2
    }
    var obj1 = Object.assign(obj);
    obj1.a = 3;
    console.log(obj.a) // 3

    3.使用等于号 =

    let a = [0, 1, 2, 3, 4];
    let b = a;
    console.log(a === b);
    a[0] = 1;
    console.log(a, b);

  4.实现深拷贝的方法

    1.使用递归去拷贝所有层级的属性

    let a = [1, 2, 3, 4, 5];
    let b = deepClone(a);
    function deepClone(obj){
      let objClone = Array.isArray(obj) ? [] : {};
      if (obj && typeof obj === "object") {
        for(key in obj) {
          // 判断对象是否包含特定的自身属性,返回Boolean
          if(obj.hasOwnProperty(key)) {
            // 判断 obj 子元素是否为对象,如果是,递归复制
            if(obj[key] && typeof obj[key] === 'object') {
              objClone[key] = deepClone(obe[key])
            } else {
              objClone[key] = obj[key]
            }
          }
        }
      }
      return objClone;    
    }

    2.通过 JSON 对象来实现深拷贝

      // 缺点:无法实现对对象中方法的拷贝,会显示为 undefined
      let a = [1,2,3,4,5];
      let b = JSON.parse(JSON.stringify(a));

    3.通过 jQuery 的 extend 方法实现深拷贝

      let arr = [1,2,3,4];
      let bbb = $.extend(true, [], array);// true 为深拷贝,false为浅拷贝

    4.可以通过 lodash 函数库实现深拷贝

      let res = _.clone(arr);

    5.Reflect方法

      // 代理法
      function deepClone(obj) {
        if(!isObject(obj)){// 判断是否为对象
          throw new Error('obj 不是一个对象')
        }
        let isArray = Array.isArray(obj);
        let cloneObj = isArray ? [...obj] : {...obj};
        Reflect.ownKeys(cloneObj).forEach(key => {
          cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
        })
        return cloneObj;
      }

    6.手动实现深拷贝

      let obj = {a: 1, b: 2};
      let obj2 = {a: obj.a, b: obj.b};

    7. 如果对象的 value 时基本类型的话,也可以用 Object.assign 来实现深拷贝,但是要把它赋值给一个空对象

      var obj = {a: 1, b: 2}
      var obj1 = Object.assign({}, obj);// obj赋值给一个空{}

    8.使用 slice 实现对数组的深拷贝

      // 但数组里面的值是基本数据类型,比如 String,Number,Boolean 时,属于深拷贝
      // 当数组里面的值时引用数据类型比如 Object, Array时,属于浅拷贝
      let a = [1,2,3];
      let b = a.slice(0);

    9.用 concat 实现对数组的深拷贝

    // 当数组里面的值是基本数据类型,比如String, Number, Boolean时,属于深拷贝
    let a = [1,2,3];
    let b = a.concat();
    // 当数组里面的值是引用数据类型,比如Object,Array时,属于浅拷贝
    let a = [{a: 1},{b: 2}];
    let b = a.concat;

    10.使用 let newObj = Object.create(oldObj) 可以达到深拷贝的效果

      function deepClone(initalObj, finalObj){
        var obj = finalObj || {};
        for(var i in initalObj) {
          var prop = initalObj[i];// 难免相互引用对象导致死循环,比如initalObj.a = initalObj
          if(prop === obj) {
            continue;
          }
          if (typeof prop === 'object') {
            obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
          } else {
            obj[i] = prop;
          }
        }
        return obj;
      }

    11.使用扩展运算符实现深拷贝

      // 当value是基本数据类型,比如String,Number,Boolean时,是可以使用拓展运算符进行深拷贝的
      // 当value是引用类型的值,比如Object,Array,引用类型进行深拷贝也只是拷贝了引用地址,所以属于浅拷贝
      var car = {sf: "james", pf: "davis", cf: "cf"}
      var car1 = { ...car, pf: "kobe" }
      console.log(car1); // { sf: "james", pf: "davis", cf: "cf" }
      console.log(car); // { sf: "james", pf: "kobe", cf: "cf" }

10.用on给动态添加的元素绑定hover事件,不会生效

  在jQuery中,hover() 函数本身是对 mouseenter && mouseleave 的封装,然而在原生 event 中,并没有 hover 这一事件,所以在传递参数 hover 时,并不会有任何的效果。

  如果我想绑定类似 hover 的效果,可以绑定两个事件 mouseenter && mouseleave + function ,样式就用类名来 toggle, 也可以在map里面,一个事件对应一个function

  $('ul.course').on('mouseenter mouseleave', 'li', function(){
    $(this).toggleclass('borderClass');// 鼠标移入移出改变 class
  })

11.JSON.stringify() 和 JSON.parse()

  JSON.stringify({'a': '1', 'b': '2'});
  // '{'a': '1', 'b': '2'}' 从一个对象中解析出字符串

  JSON.parse('{'a': '1', 'b': '2'}');
  // Object{a:'1', 'b': '2'}  从一个字符串中解析出JSON对象

12.for...in 与 for...of 的区别

  对于数组的遍历,for...in 会返回数组中所有可枚举的属性(包括原型链上可枚举的属性),for...of 只返回数组的下标对应的属性值

  for...of 循环的原理其实也是利用了遍历对象内部的 iterator 接口,将 for...of 循环分解成最原始的 for 循环,内部实现的机制可以这么理解

  // 1.for...of 遍历获取的是对象的键值,for...in 获取的是对象的键名
  let arr = ['one', 'two', 'three'];
  for(let i in arr){
    console.log(i);// 分别输出 0 1 2
  }
  for(let i of arr){
    console.log(i);// 分别输出 one two three
  }   // 2.对于普通对象,没有部署原生的 iterator 接口,直接使用 for...of 会报错
  let obj ={name: 'zhangning187', age: '24'}
  for(let key of obj) {
    console.log(key);// obj is not iterable
  }   // 可以使用 for...in 循环遍历键名
  for(let key in obj) {
    console.log(key);// name age
  }
  // 也可以使用 Object.keys(obj) 方法将对象的键名生成一个数组,然后遍历这个数组
  for(let key of Object.keys(obj)) {
    console.log(key);// name age
  }   // 3.for...in 循环不仅遍历数字键名,还会遍历手动添加的其他键,甚至包括原型链上的键。for...of则不会这样
  let array = [1, 2, 3];
  arr.name = 'zhangning187';// 手动添加的键
  Array.prototype.age = '23';// 原型链上的键
  for(let i in arr) {
    console.log(i);// 1 2 3 name age
  }
  
  // 4.forEach 循环无法中途跳出,break 命令或 return 命令都不能奏效
  let arr1 = [1, 2, 3, 4]
  arr.forEach(i=>{
    if(i == 2) return;// 它会像 continue 一样,跳过当前循环继续执行下一次循环
    console.log(i);// 1 3 4
  })
  for...of 循环可以与 break、continue、return 配合使用,跳出循环   // 5.无论是 for...in 还是 for...of 都不能遍历出 Symbol 类型的值,遍历 Symbol 类型的值需要用Object.getOwnPropertySymbols()方法
  let a = Symbol('a')
  let b = Symbol('b')
  let obj = {
    [a]: 'zhang',
    [b]: 'ning',
    c: '23',
    d: 'web'
  }
  for(let key in obj) {
    console.log(key);// c d
  }
  let objSymbols = Object.getOwnPropertySymbols(obj)
  console.log(objSymbols);// [Symbol(a), Symbol(b)]
  objSymbols.forEach(i=>{
    console.log(obj[i]);// zhang ning
  })

  // Reflect.ownKeys 方法可以返回所有类型的键名,包括常规键名和 Symbol 键名
  let keyArr = Reflect.ownKeys(obj)
  console.log(keyArr);// ["c", "d", Symbol(a), Symbol(b)]

  for...in 循环主要是为了遍历对象,不适用于遍历数组

  for...of 循环可以用来遍历数组、类数组对象、字符串、Set、Map、Generator 对象

  

开发过程中遇到的js知识点总结,面试题等,持续更新的更多相关文章

  1. 开发过程中 的一些 补充知识点 + 关于mysql中的日期和时间函数?

    参考: https://www.jb51.net/article/23966.htm https://yq.aliyun.com/articles/260389 mysql中的 日期格式是: HHHH ...

  2. 【前端面试】Vue面试题总结(持续更新中)

    Vue面试题总结(持续更新中) 题目参考链接 https://blog.csdn.net/weixin_45257157/article/details/106215158 由于已经有很多前辈深造VU ...

  3. js坑爹笔试题目汇总(持续更新中)

    把你的面试官问倒,你就是一个合格的面试者了,以下总结一些易错的js笔试题目,会持续更新中.欢迎关注 1,考察this var length = 10 function fn(){ alert(this ...

  4. 开发中常用的JS知识点集锦

    索引 1.对象深拷贝 2.网络图片转base64, 在线图片点击下载 3.常用CSS样式记录(超出宽高省略展示/播放icon/按钮背景颜色渐变...) 4.对象深拷贝 5.对象深拷贝 6.对象深拷贝 ...

  5. 从项目中总结的js知识点

    1. 数字字符串和数字进行比较可以得出正确结果,却不能正确判断是否在一个数字数组中.如以下程序: var s = '8', n = 8, arr = [1,2,8,9]; console.log(s= ...

  6. JAVA中一些需要记录的知识点(进阶部分)···持续更新

    1.JAVA中的相对路径 file = new file("")与file = new file("./")方式相同,该路径为整个project的根目录(实际上 ...

  7. JavaScript中一些你不一定知道的问题(持续更新中。。。。)

    一些js的问题与解析 1) ["1","2","3"].map(parseInt);的运行结果是? A.["1",&qu ...

  8. django项目实际工作中的配置以及一些有用的小工具(持续更新)

    常用pycharm快捷键:   https://www.cnblogs.com/luolizhi/p/5610123.html   Ctrl + F1  显示错误 Ctrl + Alt + Space ...

  9. Myeclipse中web project各种常见错误及解决方法(持续更新)

    创建web project时的问题 error:Install Dynamic web Module Facet卡住 solution:把网络关掉再创建就可以 Servlet error:The se ...

随机推荐

  1. hdu5501 The Highest Mark

    Problem Description The SDOI in 2045 is far from what it was been 30 years ago. Each competition has ...

  2. Checkout Assistant CodeForces - 19B

    题意: 给你n个物品,每个物品有一个价格ci和一个支付时间ti,在这个ti时间内,你可以免费拿ti个物品.问你想要带走这n个物品最小需要多少钱 题解: 原本还想着贪心去写,但是好像贪心写不了,,,不属 ...

  3. nginx 80端口跳转到443

    nginx配置文件80配置中增加 rewrite ^ https://$http_host$request_uri? permanent; 如图: https://blog.csdn.net/jian ...

  4. kubernetes进阶(四)服务暴露-ingress控制器之traefik

    上一章我们测试了在集群内部解析service名称, 下面我们测试在集群外部解析: 根本解析不到,因为我们外部用的dns是10.4.7.11,也就是我们的自建bind dns,这个DNS服务器上也没有响 ...

  5. 计算机网络基础篇-ppp协议

    所谓的PPP协议是点对点协议,是目前使用最广泛的数据链路层的协议.大部分用户使用电话线拨号入网的,从用户计算机到ISP的链路所使用的数据链路层协议就是PPP协议. 首先介绍下拨号入网的过程.因特网服务 ...

  6. C# 数据类型(2)

    String char的集合 string name = "John Doe"; 双引号,char是单引号string是不可变的,一旦初始化后就不能变了,每次对已存在的string ...

  7. Web 前端页面性能监控指标

    Web 前端页面性能监控指标 性能监控 / 性能指标 / 性能优化 白屏时间计算 FCP 白屏时间:从浏览器输入地址并回车后到页面开始有内容的时间: 首屏时间计算 FMP 首屏时间:从浏览器输入地址并 ...

  8. React 组件之间通信 All in One

    React 组件之间通信 All in One 组件间通信 1. 父子组件之间通信 props 2. 兄弟组件之间通信 3. 跨多层级的组件之间通信 Context API https://react ...

  9. js bitwise operation all in one

    js bitwise operation all in one 位运算 & 按位与 | 按位或 ^ 按位异或 / XOR let a = 5; // 000000000000000000000 ...

  10. Async Programming All in One

    Async Programming All in One Async & Await Frontend (async () => { const url = "https:// ...