这篇文章没有按照直接贴上源码来分析的方式去写,主要原因是原文章中已经分析的很详细了;另一方面,感觉通过问答的方式思考问题学习效果更好.
这次通过回答问题的方式来巩固自己的学习成果.
看完源码,又看到了评论区有大佬抛出问题. 感觉这些问题和自己阅读源码时遇到的问题很相似,故用这些问题来检验自己的学习成果.
使用instanceof方法
[] instanceof Array;// true
{} instanceof Object;// true
Object.prototype.toString.call(file) == '[object File]'
待补充
FormData用来以键值对的形式发送表单数据.
// 利用构造函数来创建实例var formData = new FormData();// append添加数据formData.append(key,value);// 通过ajax来发送数据var request = new XMLHttpRequest();request.open('GET','https://www.baidu.com');request.send(formData);
判断方法为:
formData instanceof FormData //trueObject.prototype.toString.call(formData) //[object FormData]
字符串中的trim方法可以去除首尾中指定的字符.
源码中的正则表达式用来去除字符串首位的空白字符:
str.replace(/^\s+|\s+$/g, '');
若想去除字符串中的所有空格,直接匹配\s
即可
const str = ' 123 ';
const regex = /\s/g;
console.log(str.replace(regex,''));// '123'
直接看源码遍历的方法:
function forEach(obj, fn) {if (obj === null || typeof obj === 'undefined') {return;}if (typeof obj !== 'object') {obj = [obj];}if (isArray(obj)) {for (var i = 0, l = obj.length; i < l; i++) {fn.call(null, obj[i], i, obj);}} else {for (var key in obj) {if (Object.prototype.hasOwnProperty.call(obj, key)) {fn.call(null, obj[key], key, obj);}}}
}
1.传入为null与undefined类型不做遍历
2.非对象类型包裹一层数组(转换成数组)
3.如果类型为数组,直接for循环遍历,每次循环调用传入的函数fn
4.如果类型为对象,先进行if判断.for…in是可以遍历到对象原型上的属性的,语句Object.prototype.hasOwnProperty.call(obj, key)
可以防止遍历到对象原型上的属性.然后进行函数调用.
看源码:
function merge(/* obj1, obj2, obj3, ... */) {var result = {};function assignValue(val, key) {if (isPlainObject(result[key]) && isPlainObject(val)) {result[key] = merge(result[key], val);} else if (isPlainObject(val)) {result[key] = merge({}, val);} else if (isArray(val)) {result[key] = val.slice();} else {result[key] = val;}}for (var i = 0, l = arguments.length; i < l; i++) {forEach(arguments[i], assignValue);}return result;
}
1.遍历传入的每一个参数,调用forEach
方法;相当于每一个传入的对象都调用了assignValue
方法.(在forEach方法中,默认为assignValue函数传入参数,此时参数val为对象属性值,key为对象属性名)
2.如果result结果为空,且val为对象,进行递归,以原result为基本
3.如果result结果不为空,且val为对象,以空对象为基本
4.如果是数组,使用slice来返回新数组
5.如果是其它类型,直接赋值
感觉这个问题问的是: 如何防止数组产生引用传递?
result[key] = val.slice();
数组的slice方法将返回一个浅拷贝后的新数组,如果直接将数组赋值给对象,将会造成引用传递
,使用slice方法可以解决这个问题.
最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。
有需要的小伙伴,可以点击下方卡片领取,无偿分享