1.取出对象中一部分放到另一个对象中
今天下午在掘金摸鱼的时候,看见有一个小同学发了一个沸点
嗯嗯 ,日常要我写的话,以前可能我也会这么写,但是经过我最近一段时间的学习,我可能会用解构赋值来写
const objOne = {
name: 'xiaoMing',
age: 18,
id: 1234,
gender: 1
}
const { name, id } = objOne;
const objTwo = { name, id };
我可能会像上面这样写,这些些真的很优雅吗,我觉得跟上面那位小同学写的也没什么区别,还多一行代码,并不是一个好的方案,像我这么机灵的搜索引擎工程师,那么我就开始Google一下,于是找到一个讨论贴,针不戳,里面果然有几种比较秒的写法,显得有点高端。
(1)第一种
const objOne = {
name: 'xiaoMing',
age: 18,
id: 1234,
gender: 1
}
const { age, gender, ...objTwo } = objOne;
这种也是利用的对象解构,把剩余的值赋给了objTwo,但是如果我原对象中有30个属性,我只需要取两个呢,那我岂不是得写很多。
(2)第二种
const objOne = {
name: 'xiaoMing',
age: 18,
id: 1234,
gender: 1
}
const objTwo = (({ name, id }) => ({ name, id }))(objOne)
上面这种也是解构,不过这里用了一个立即执行函数,还是比较秒的,但是本质上还是解构的思想,跟上面的有同样的问题,假如我要取28个属性呢,那岂不是要写很多。
(3)第三种
const objOne = {
name: 'xiaoMing',
age: 18,
id: 1234,
gender: 1
}
const pick = (obj, arr) => arr.reduce((iter, val) =>
(val in obj && (iter[val] = obj[val]), iter), {});
const objTwo = pick(objOne, ['name', 'id']);
这种刚看是不是还有点不明白,首先箭头函数箭头后面不写大括号{}的时候,会自动return,这是箭头函数带的特性,再就是 (val in obj && (iter[val] = obj[val]), iter) 这一句代码是不是看着有点不是很懂,前面倒是知道,就是判断,那这个逗号是什么意思呢,其实我刚看也没看懂,就直接翻了一下 逗号操作符--MDN
也就是说上面这一行代码会返回每次的操作结果,然后用这个操作结果再进行下一次操作,上面的代码也就相当于:
const objOne = {
name: 'xiaoMing',
age: 18,
id: 1234,
gender: 1
}
const pick = (obj, arr) => arr.reduce((iter, val) => {
if (val in obj && (iter[val] = obj[val])) {
return iter
}
}, {});
const objTwo = pick(objOne, ['name', 'id']);
但是上面用逗号写的确实会更简洁,对不懂逗号操作符的人来说可能不是很明了。
2.判断一个变量同时等于多个数值
这是今天看B站上的一个UP的视频里面,UP提出来的,当然之前我也看到过,只是没有仔细的研究,只是今天看视频又看见了,想着连着上面那一题一起记录一下吧,毕竟好记性不如烂笔头嘛??
if (a == 1 && a == 2 && a == 3) {
console.log('星空海绵');
}
上面写一段是什么代码可以让这个判断成立,执行打印的代码,首先一看到这个题目,大家应该想到,想要这个判断成立,a肯定得是一个变化得值,每使用一次就加1,那么这个判断才有可能成立,好了,怎样让这个判断成立的思路已经有了,现在的问题就是怎么让a每使用一次就加1呢。 首先我们来看一下 == 操作符成立的条件:
- 1.如果两个操作数都是对象,则仅当两个操作数都引用同一个对象时才返回true。
- 2.如果一个操作数是null,另一个操作数是undefined,则返回true。
- 3.如果两个操作数是不同类型的,就会尝试在比较之前将它们转换为相同类型:
- 1.当数字与字符串进行比较时,会尝试将字符串转换为数字值。
- 2.如果操作数之一是Boolean,则将布尔操作数转换为1或0。true转成1,false转成0。
- 3.如果操作数之一是对象,另一个是数字或字符串,会尝试使用对象的valueOf()和toString()方法将对象转换为原始值。
- 4.如果操作数具有相同的类型,则将它们进行如下比较:
- 1.String:true仅当两个操作数具有相同顺序的相同字符时才返回。
- 2.Number:true仅当两个操作数具有相同的值时才返回。+0并被-0视为相同的值。如果任一操作数为NaN,则返回false。
- 3.Boolean:true仅当操作数为两个true或两个false时才返回true。
(1)第一种解法
看到上面 == 运算符的相关成立条件后,我们再来分析上面这一题,当 a 是 number 类型时,只有每次访问后都加1上面的判断才会成立。那么我们看下上面的代码,这个a没用var或者let及const定义,那就是隐式变量,当然我们也可在上面定义a,就单纯这个式子而言,a是隐式变量,隐式变量再浏览器中是挂在全局对象window下面的,也就是说a是window对象下的一个属性,然后对象有一个 Object.defineProperty() 方法,这个方法能定义和修改一个对象上的属性,并且返回此对象。
let _default = 0
Object.defineProperty(window, 'a', {
get() {
return ++_default;
}
})
if (a == 1 && a == 2 && a == 3) {
console.log('星空海绵');
}
此时通过上面这段代码我们发现这个判断成立,此时如果我们把 == 改成 === 成立吗,照样是成立的,因为此时a每次增加1并保持自己的类型为number,也就是说上面这段代码不仅适用于 == ,同时也适用于 === 。
(2)第二种解法
看到上面 == 运算符的介绍,我们发现 如果操作数之一是对象,另一个是数字或字符串,会尝试使用对象的valueOf()和toString()方法将对象转换为原始值。 有这么一个规则,也就是说假如现在上面的a是对象的话,会尝试使用valueOf方法和toSting方法,那么我们去修改这两个方法中的其中一个行吗
let a = {
_default: 0,
valueOf: function () {
return ++this._default;
}
}
if (a == 1 && a == 2 && a == 3) {
console.log('星空海绵');
}
let a = {
_default: 0,
toString: function () {
return ++this._default;
}
}
if (a == 1 && a == 2 && a == 3) {
console.log('星空海绵');
}
以上两种方法都可以,一个是重写a对象的valueOf方法,一个是重写对象的toString()方法。
3.深入类型转换
首先上题目
console.log(({} + {}).length);
console.log(([] + []).length);
console.log(([] + {}).length);
console.log((function () { }).length);
上面这4个console分别打印什么,首先第一个其实是两个空对象相加,那么空对象怎么相加呢,它们会自动转成字符串相加,也就是调用toString方法,也就是说{}.toSting(),那么这个结果是什么呢,这个结果是 [object object],此时你是不是想到了判断类型的 Object.prototype.toString.call() ,既然知道原理了,那第一个console的答案就是 "[object object]"+"[object object]",也就是30, 第二个可能不用说大家都知道是0,因为[]空数组转换成数值类型是0,根据上面两题我们知道这个答案是 0+"[object object]",也就是15,那么最后一题呢,我们不妨打印 console.dir(function () { }); 看一下,发现这个里面带了一个length属性,那么这个length属性是什么呢,其实是参数列表的个数,相当于 arguments.length,所以最后一个的结果也是0。
console.log(({} + {}).length); // 30
console.log(([] + []).length); // 0
console.log(([] + {}).length); // 15
console.log((function () { }).length); // 0
完!
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!