前端学习--知识整理

一、深、浅拷贝

作者:浪里行舟
链接:https://juejin.im/post/5b5dcf8351882519790c9a2e
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

(1)深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的

原因:
基本数据类型的特点:直接存储在栈(stack)中的数据
引用数据类型的特点:栈内存中存储地址,真实的数据存放在堆内存里
在这里插入图片描述
浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

(2)赋值和浅拷贝的区别

当我们把一个对象赋值给一个新的变量时,赋的其实是该对象的在栈中的地址,而不是堆中的数据。也就是两个对象指向的是同一个存储空间,无论哪个对象发生改变,其实都是改变的存储空间的内容,因此,两个对象是联动的

在这里插入图片描述

(3)浅拷贝的实现方式

1.Object.assign()

Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。但是 Object.assign()进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身。

var obj = { a: {a: "kobe", b: 39} };
var initalObj = Object.assign({}, obj);
initalObj.a.a = "wade";
console.log(obj.a.a); //wade

2.Array.prototype.concat()

let arr = [1, 3, {
    username: 'kobe'
    }];
let arr2=arr.concat();    
arr2[2].username = 'wade';
console.log(arr);

3.Array.prototype.slice()

let arr = [1, 3, {
    username: ' kobe'
    }];
let arr3 = arr.slice();
arr3[2].username = 'wade'
console.log(arr);

关于Array的slice和concat方法的补充说明:Array的slice和concat方法不修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。

4.lodash_.clone(value):浅拷贝

(4)深拷贝的实现方式

1.JSON.parse(JSON.stringify())

let arr = [1, 3, {
    username: ' kobe'
}];
let arr4 = JSON.parse(JSON.stringify(arr));
arr4[2].username = 'duncan'; 
console.log(arr, arr4)

在这里插入图片描述
原理: 用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝。

2.lodash_.cloneDeep(value):深拷贝

(5)这种方法虽然可以实现数组或对象深拷贝,但不能处理函数

这是因为JSON.stringify() 方法是将一个JavaScript值(对象或者数组)转换为一个 JSON字符串,不能接受函数

2.手写递归方法
递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝

二、JS两位小数相加会出现多位小数

在这里插入图片描述

原因:JS小数精度问题

解决方法:

根据需求要保留n位小数的,数据在计算前先 乘于n个10,再去计算。计算完成后再除于 n个10
在这里插入图片描述

三、css属性overflow属性定义溢出元素内容区的内容会如何处理。如果值为 scroll,不论是否需要,用户代理都会提供一种滚动机制

参数是scroll时候,必会出现滚动条。
参数是auto时候,子元素内容大于父元素时出现滚动条。
参数是visible时候,溢出的内容出现在父元素之外。
参数是hidden时候,溢出隐藏。

四、有关JavaScript中 call和apply的描述

(1)call与apply都属于Function.prototype的一个方法,所以每个function实例都有call、apply属性
(2)apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入
(3)call传入的则是直接的参数列表。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象
(4)call()方法和apply()方法的作用相同,他们的区别在于接收参数的方式不同。对于call(),第一个参数是this值没有变化,变化的是其余参数都直接传递给函数。(在使用call()方法时,传递给函数的参数必须逐个列举出来。使用apply()时,传递给函数的是参数数组)如下代码做出解释:

function add(c, d){
	return this.a + this.b + c + d;
}
var o = {a:1, b:3};
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34

五、利用CSS Sprites(精灵图)能减少图片的字节,能很好地减少网页的http请求,从而大大的提高页面的性能

六、浏览器内核

Wekbit是一个开源的Web浏览器引擎,也就是浏览器的内核。Apple的Safari, Google的Chrome, Nokia S60平台的默认浏览器,Apple手机的默认浏览器,Android手机的默认浏览器均采用的Webkit作为器浏览器内核。Webkit的采用程度由 此可见一斑,理所当然的成为了当今主流的三大浏览器内核之一。另外两个分别是Gecko和Trident,大名鼎鼎的Firefox便是使用的Gecko 内核,而微软的IE系列则使用的是Trident内核。

另外,搜狗浏览器是双核的,双核并不是指一个页面由2个内核同时处理,而是所有网页(通常是标准通用标记语言的应用超文本标记语言)由webkit内核处理,只有银行网站用IE内核

七、原型链

参看资料:https://www.nowcoder.com/questionTerminal/133157fbfae443d18780d5cec6d3334e

function A(x){
	this.x = x;
}
A.prototype.x = 1;

function B(x){
	this.x = x;
}
B.prototype = new A();
var a = new A(2), b = new B(3);
delete b.x;

//答案:2, undefined

//解析:
B.prototype = new A();//形成原型链
//B.prototype = { x: undefined}; 因为A()里存在this.x = x,但是new的时候没有传参,所以x == undefined
var a = new A(2);
//传入参数2,通过this.x = x,得到a.x == 2;
b = new B(3);
//同理 b.x == 3;
delete b.x;
//因为删除了b.x(注意这里的x是B自身的x,而不是prototype里的x。由于删除了b.x,b.x会过原型链找到构造函数A里面的this.x=x但是没有传参赋值,所以undefined)

八、同步、异步

console.log(1);
setTimeout(() => {console.log(2)}, 0);
console.log(3);
Promise.resolve(4).then(b => {
console.log(b);
});
console.log(5);
//1 3 5 4 2

console.log() -> 同步
promise -> 异步,微任务
setTimeout -> 异步,宏任务
执行顺序: 同步 > (异步,微任务) > (异步,宏任务)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值