开发过程中遇到的js知识点总结,面试题等,持续更新
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知识点总结,面试题等,持续更新的更多相关文章
- 开发过程中 的一些 补充知识点  + 关于mysql中的日期和时间函数?
		
参考: https://www.jb51.net/article/23966.htm https://yq.aliyun.com/articles/260389 mysql中的 日期格式是: HHHH ...
 - 【前端面试】Vue面试题总结(持续更新中)
		
Vue面试题总结(持续更新中) 题目参考链接 https://blog.csdn.net/weixin_45257157/article/details/106215158 由于已经有很多前辈深造VU ...
 - js坑爹笔试题目汇总(持续更新中)
		
把你的面试官问倒,你就是一个合格的面试者了,以下总结一些易错的js笔试题目,会持续更新中.欢迎关注 1,考察this var length = 10 function fn(){ alert(this ...
 - 开发中常用的JS知识点集锦
		
索引 1.对象深拷贝 2.网络图片转base64, 在线图片点击下载 3.常用CSS样式记录(超出宽高省略展示/播放icon/按钮背景颜色渐变...) 4.对象深拷贝 5.对象深拷贝 6.对象深拷贝 ...
 - 从项目中总结的js知识点
		
1. 数字字符串和数字进行比较可以得出正确结果,却不能正确判断是否在一个数字数组中.如以下程序: var s = '8', n = 8, arr = [1,2,8,9]; console.log(s= ...
 - JAVA中一些需要记录的知识点(进阶部分)···持续更新
		
1.JAVA中的相对路径 file = new file("")与file = new file("./")方式相同,该路径为整个project的根目录(实际上 ...
 - JavaScript中一些你不一定知道的问题(持续更新中。。。。)
		
一些js的问题与解析 1) ["1","2","3"].map(parseInt);的运行结果是? A.["1",&qu ...
 - django项目实际工作中的配置以及一些有用的小工具(持续更新)
		
常用pycharm快捷键: https://www.cnblogs.com/luolizhi/p/5610123.html Ctrl + F1 显示错误 Ctrl + Alt + Space ...
 - Myeclipse中web project各种常见错误及解决方法(持续更新)
		
创建web project时的问题 error:Install Dynamic web Module Facet卡住 solution:把网络关掉再创建就可以 Servlet error:The se ...
 
随机推荐
- 牛客编程巅峰赛S1第3场 - 青铜&白银   A.位数求和
			
题意:求所有\(n\)位数每位之和等于\(m\)的数的和. 题解:数据范围非常小,我们可以直接暴力枚举\(t\)到\(10*t\)的所有数字,逐位分解判断即可. 代码: class Solution ...
 - Kubernets二进制安装(11)之部署Node节点服务的kubelet
			
集群规划 主机名 角色 IP地址 mfyxw30.mfyxw.com kubelet 192.168.80.30 mfyxw40.mfyxw.com kubelet 192.168.80.40 注意: ...
 - Linux命令:sysctl
			
sysctl命令用于运行时配置或查看内核参数,这些参数位于/proc/sys目录下.可以使用sysctl命令来设置或重新设置网络联网功能,如:IP转发.IP碎片去除以及源路由检查等.用户可以编辑/et ...
 - spring再学习之基本概念
			
二.spring之IOC与DI 注入的方式: set方法注入: 构造方法注入: 字段注入: 注入类型: 值类型注入:8中基本类型 引用类型注入: BeanFaactory是原始接口:功能比较单一. A ...
 - Python_变量作用域与修改
			
引用全局变量,不需要golbal声明,修改全局变量,需要使用global声明,特别地,列表.字典等如果只是修改其中元素的值(而不是整体赋值的形式),可以直接使用全局变量,不需要global声明. 参考 ...
 - woj1009 最短路 The Legend of Valiant Emigration
			
title: woj1009 最短路 The Legend of Valiant Emigration date: 2020-03-07 categories: acm tags: [acm,最短路, ...
 - involution 内卷化
			
involution 内卷化 虽然不熟悉 involution,但是我想起另外两个常用词:evolution(进化)和 revolution(革命). 它们共同的词根volute,拉丁语原意是&quo ...
 - 如何配置 webpack 支持 preload, prefetch, dns-prefetch
			
如何配置 webpack 支持 preload, prefetch, dns-prefetch webpack , preload, prefetch https://webpack.js.org/p ...
 - js double 精度损失 bugs
			
js double 精度损失 bugs const arr = [ 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01 ]; // [ ...
 - taro 三端开发
			
taro 三端开发 wx 小程序, alipay 小程序,H5 https://taro-docs.jd.com/taro/docs/GETTING-STARTED.html#h5 https://t ...