Daily-Interview-Question
Daily-Interview-Question copied to clipboard
第 38 题:下面代码中 a 在什么情况下会打印 1?
题目如下
var a = ?;
if(a == 1 && a == 2 && a == 3){
conso.log(1);
}
答案解析 因为==会进行隐式类型转换 所以我们重写toString方法就可以了
var a = {
i: 1,
toString() {
return a.i++;
}
}
if( a == 1 && a == 2 && a == 3 ) {
console.log(1);
}
let a = [1,2,3];
a.toString = a.shift;
if( a == 1 && a == 2 && a == 3 ) {
console.log(1);
}
这题考察的应该是类型的隐式转换,考引用类型在比较运算符时候,隐式转换会调用本类型toString或valueOf方法. 解答:
var a = {num:0}; a.valueOf = function(){ return ++a.num } if(a == 1 && a == 2 && a == 3){ console.log(1); }
这个题目考察==的隐式转换吧
利用toString
let a = {
i: 1,
toString () {
return a.i++
}
}
if(a == 1 && a == 2 && a == 3) {
console.log('1');
}
利用valueOf
let a = {
i: 1,
valueOf () {
return a.i++
}
}
if(a == 1 && a == 2 && a == 3) {
console.log('1');
}
数组这个就有点妖了
var a = [1,2,3];
a.join = a.shift;
if(a == 1 && a == 2 && a == 3) {
console.log('1');
}
ES6的symbol
let a = {[Symbol.toPrimitive]: ((i) => () => ++i) (0)};
if(a == 1 && a == 2 && a == 3) {
console.log('1');
}
let a = {
gn: (function* () {
yield 1;
yield 2;
yield 3;
})(),
valueOf() {
return this.gn.next().value;
}
};
Object.defineProperty(window, 'a', { get: function() { return this.value += 1; } });
要改下,不然报错。你这个挺好,可以做 ===
Object.defineProperty(window, 'a', {
get: function() {
if (this.value) {
return this.value += 1
} else {
return this.value = 1;
}
}
});
Object.defineProperty(window, 'a', { get: function() { return this.value += 1; } });
要改下,不然报错。你这个挺好,可以做 ===
Object.defineProperty(window, 'a', { get: function() { if (this.value) { return this.value += 1 } else { return this.value = 1; } } });
精简一下代码:
Object.defineProperty(window, 'a', {
get: function() {
return this.value = this.value ? (this.value += 1) : 1;
}
});
一开始没转过来,群里老哥提了一声才想到这个方向
var a = Object.create({
count: 0,
valueOf: function() {
return ++this.count;
}
});
if (a == 1 && a == 2 && a == 3) {
console.log(1);
}
第一反应想到的是a = console.log(1)😂😂
@XinJack 感觉你这个才是最优解啊,半天说不出一句话。
@XinJack console.log() 的返回值是 undefined
数组这个 a.join = a.shift; 没看懂啊
数组这个 a.join = a.shift; 没看懂啊
把 shift 方法的引用 ,放到 a.join 上的。覆盖原来的 join 方法
数组这个 a.join = a.shift; 没看懂啊
把 shift 方法的引用 ,放到 a.join 上的。覆盖原来的 join 方法
为啥a==1之后会执行join(shift)函数?
@seujzhang 执行 a ==1
会进行隐式转换
@seujzhang 执行
a ==1
会进行隐式转换
小白求教下,是不是这样的:在执行a==1的时候,会尝试对a进行隐式转换,此时隐式转换会调用Array的join方法,而此时join方法被shift覆盖,所以调用的实际上是shift方法,弹出1,然后相等,再弹出2相等,弹出3相等,最后console执行。
这个题目考察==的隐式转换吧
利用toString
let a = { i: 1, toString () { return a.i++ } } if(a == 1 && a == 2 && a == 3) { console.log('1'); }
利用valueOf
let a = { i: 1, valueOf () { return a.i++ } } if(a == 1 && a == 2 && a == 3) { console.log('1'); }
数组这个就有点妖了
var a = [1,2,3]; a.join = a.shift; if(a == 1 && a == 2 && a == 3) { console.log('1'); }
ES6的symbol
let a = {[Symbol.toPrimitive]: ((i) => () => ++i) (0)}; if(a == 1 && a == 2 && a == 3) { console.log('1'); }
这个a.join = a.shift 是什么意思 还能这样子赋值麽。
第一反应想到的是a = console.log(1)😂😂
为什么总有一些让人眼前一亮的答案😂
对象转原始类型 Symbol.toPrimitive 优先级最高
var a = {
i: 1,
valueOf() {
return a.i++;
},
toString() {
return a.i++;
},
[Symbol.toPrimitive]() {
return a.i++;
}
}
if ( a == 1 && a == 2 && a == 3 ) {
console.log(1);
}
来一手另类的👋👋
Object.prototype.toString = (function () {
var t = 1;
return function () {
return t++;
}
})()
var a = {}
a == 1 && a == 2 && a == 3 // true
var a = {
value: 1,
toString: function() {
return a.value++;
},
};
if(a == 1 && a == 2 && a == 3){
console.log(1);
}
第一反应想到的是a = console.log(1)
蔡徐坤行为-_-!!!
第一反应想到的是a = console.log(1)joyjoy
为什么总有一些让人眼前一亮的答案
这操作属实有点优秀啊
var a = true;
let i = 1; let a = new Proxy({},{ i:1, get(){ return ()=> this.i++ } }) console.log(a==1&&a==2&&a==3)
解释一下好吗?
var a = {
i: 1,
toString () {
return this.i++
}
}
if (a == 1 && a == 2 && a == 3) {
console.log('真棒')
}
为什么a==true不行?
为什么a==true不行?
规范 11.9.3.6-7 是这样说的: (1) 如果 Type(x) 是布尔类型,则返回 ToNumber(x) == y 的结果; (2) 如果 Type(y) 是布尔类型,则返回 x == ToNumber(y) 的结果。 所以true==2;会先将true转为1,1==2即false
var a = {
arr: [1,2,3],
toString: function() {
return this.arr.shift();
}
};
题目如下
var a = ?; if(a == 1 && a == 2 && a == 3){ conso.log(1); }
答案解析 因为==会进行隐式类型转换 所以我们重写toString方法就可以了
var a = { i: 1, toString() { return a.i++; } } if( a == 1 && a == 2 && a == 3 ) { console.log(1); }
我想提一点
楼上这些答案已经很好了。我想请教一下在什么场景下才会应用到题目中的代码?
楼上这些答案已经很好了。我想请教一下在什么场景下才会应用到题目中的代码?
没有使用场景,仅仅是考察==隐式转换这个知识点。
突然发现js编程的乐趣~~~
var a = { toString: function(){ //隐式转换,对象和数字做对比时,系统自动调用 this.index ++; return this.index; }, index:0 }
if(a ==1 && a==2 && a==3){ console.log(1) }
// 使用valueOf
var a = {
value: 1,
valueOf: function() {
return this.value++
}
}
// 使用toString
var a = {
value: 1,
toString: function() {
return this.value++
}
}
但是请注意,如果两个同时存在,则valueOf优先级高于toString,而且 String(a) 调用的是toString
第一反应想到的是a = console.log(1)😂😂
JavaScript 的乐趣就在于此 💯
var a = ?;
if(a == 1 && a == 2 && a == 3){
console.log(1);
}
看到答案瞬间懵逼... 这个东西反常识,写代码单元测试的人直接吐血...
数组这个 a.join = a.shift; 没看懂啊
数组隐式转换成字符串之前会执行一次join操作-> a.valueOf().join().toString()
现在都推===和typescript了,还在考这些垃圾特性...
现在都推===和typescript了,还在考这些垃圾特性...
哈哈哈哈
var a = {
num: 1,
valueOf() {
return a.num++
}
}
console.log(a == 1 && a == 2 && a == 3, '1-------')
var b = {
num: 1,
toString() {
return b.num++
}
}
console.log(b == 1 && b == 2 && b == 3, '2-------')
var c = {
num: 1,
[Symbol.toPrimitive](h) {
return c.num++
}
}
console.log(c == 1 && c == 2 && c == 3, '3-------')
var d = new Proxy(
{},
{
i: 1,
get: function() {
return () => this.i++
}
}
)
console.log(d == 1 && d == 2 && d == 3, '4-------')
efun = {
i: 1,
get: function() {
return efun.i++
}
}
Object.defineProperty(global, 'e', efun)
console.log(e == 1 && e == 2 && e == 3, '5-------')
var f = [1, 2, 3]
f.join = f.shift
console.log(f == 1 && f == 2 && f == 3, '6-------')
var g = {
i: 123,
reg: /\d/g,
valueOf() {
return this.reg.exec(this.i)[0]
}
}
console.log(g == 1 && g == 2 && g == 3, '7-------')
https://blog.csdn.net/itcast_cn/article/details/82887895
数组这个 a.join = a.shift; 没看懂啊
如何a是Array,a==1 会自动数据类型的转换,也就是调用a.join方法,而a.shift是deleteArray的第一元素并返回delete的元素,understand?
来个骚的
var a = new Number()
a.valueOf = (a=>()=>a++)(1)
if ( a == 1 && a == 2 && a == 3 ) {
console.log('1');
}
var a = 1;
if(!(a == 1 && a == 2 && a == 3)){
console.log(1);
}
@XinJack console.log() 的返回值是 undefined
但也达到了打印 1 的目的啊
@seujzhang 执行
a ==1
会进行隐式转换小白求教下,是不是这样的:在执行a==1的时候,会尝试对a进行隐式转换,此时隐式转换会调用Array的join方法,而此时join方法被shift覆盖,所以调用的实际上是shift方法,弹出1,然后相等,再弹出2相等,弹出3相等,最后console执行。
对,你打印一下a就看到了,实际上是給a添加一个join属性,这个属性就是shift方法,所以a.join是一个方法,隐士转换的时候调用a 的join()方法,而此时a自己有join属性了,就不会去Array原型链上找了,而a.join === Array.prototype.shift; 所以执行a.join()就相当于执行Array.prototype.shift方法,
let i = 0
Object.defineProperty('window', 'a', {
get:()=>{
return ++i
}
}
第一次访问a的值
在 2020-07-22 17:19:26,zengkaiz [email protected] 写道:
leti=0Object.defineProperty('window','a',{get:()=>{return++i}}
— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.
var a = [1,2,3];
a.join = a.shift;
if(a == 1 && a == 2 && a == 3){
console.log(1);
}
//
var a = {
i: 0,
toString: function(){
return this.i += 1;
}
};
if(a == 1 && a == 2 && a == 3){
console.log(1);
}
//
var a = {
i: 0,
valueOf: function(){
return this.i += 1;
}
};
if(a == 1 && a == 2 && a == 3){
console.log(1);
}
//
Object.defineProperty(window, 'a', {
get: function(){
return this.value = this.value ? (this.value +=1) : 1;
}
});
if(a == 1 && a == 2 && a == 3){
console.log(1);
}
//
var value = 0;
Object.defineProperty(window, 'a', {
get: function(){
return this.value += 1;
}
});
if(a == 1 && a == 2 && a == 3){
console.log(1);
};
来一手另类的👋👋
Object.prototype.toString = (function () { var t = 1; return function () { return t++; } })() var a = {} a == 1 && a == 2 && a == 3 // true
覆盖原型还是不太好
var a = a ? ++a : 1;
if(a == 1 && a == 2 && a == 3){
console.log(1);
}
// 下面的也能输出
if(a === 1 && a === 2 && a === 3){
console.log(1);
}
这样不香嘛
let times = 0;
var a = {
[Symbol.toPrimitive]: function () {
return ++times;
}
};
if (a == 1 && a == 2 && a == 3) {
console.log(1);
}
最先想到的是get, set, 这样好像就没有var a了, 感觉有点偏题, 不过估计知识点应该是valueOf, toString, 哈哈哈
Object.defineProperty(window, 'a', {
get: (function() {
var i = 1
return function () {
return i++
}
})(),
set: function(val) {
return val
}
})
if(a == 1 && a == 2 && a == 3){
console.log(1);
}
var a = (function b(num){
b.valueOf=function(){return ++num}
return b
})(0)
为什么a==true不行?
Boolean和其他类型比较,先被转换为Number,true被转换成 1
数组这个 a.join = a.shift; 没看懂啊
如何a是Array,a==1 会自动数据类型的转换,也就是调用a.join方法,而a.shift是deleteArray的第一元素并返回delete的元素,understand?
@ihoneys 啊?隐式类型转换还会调用 join 方法,我还以为就 toString 和 valueOf 呢,还有就是那个 拆箱时ToPrimitive,还会调用哪些方法?
var a = a ? ++a : 1; if(a == 1 && a == 2 && a == 3){ console.log(1); } // 下面的也能输出 if(a === 1 && a === 2 && a === 3){ console.log(1); }
这样不香嘛
这个在那个环境运行的,我咋没打印出来1 啊
Object.defineProperty(window, 'a', { get: function() { return this.value += 1; } });
要改下,不然报错。你这个挺好,可以做 ===
Object.defineProperty(window, 'a', { get: function() { if (this.value) { return this.value += 1 } else { return this.value = 1; } } });
精简一下代码:
Object.defineProperty(window, 'a', { get: function() { return this.value = this.value ? (this.value += 1) : 1; } });
再精简一下:
Object.defineProperty(window, 'a', {
get: function() {
return this.value = (this.value || 0) + 1;
}
});
第一反应想到的是a = console.log(1)😂😂
这都没有进 if 语句啊😂
(京东)下面代码中 a 在什么情况下会打印 1?
var a = ?; if(a == 1 && a == 2 && a == 3){ console.log(1); }
var a = {
value: 1,
toString() {
return this.value++
}
};
if(a == 1 && a == 2 && a == 3){
console.log(1); // 1
}
var a = {
arr: [1,2,3],
toString: function() {
return this.arr.shift();
}
};
if(a == 1 && a == 2 && a == 3){
console.log(1); // 1
}
var a = {
value: [1,2,3],
toString: function() {
return this.value.shift();
},
valueOf() {
return 0
}
};
console.log(a == 0) // true
if(a == 1 && a == 2 && a == 3){
console.log(1);
}
var a = {
value: [1,2,3],
toString: function() {
return this.value.shift();
},
valueOf() {
return {}
}
};
if(a == 1 && a == 2 && a == 3){
console.log(1); // 1
}
var a = {
value: [1,2,3],
toString: function() {
return {}
},
valueOf() {
return {}
}
};
// TypeError: Cannot convert object to primitive value
if(a == 1 && a == 2 && a == 3){
console.log(1);
}
- 确定两个变量是否相等是编程中的一个非常重要的操作
- 在比较字符串、数值和布尔值的相等性时,问题还比较简单;但在涉及到对象的比较时,问题就变得复杂了
- 最早的
ECMAScript
中的相等和不等操作符会在执行比较之前,先将对象转换成相似的类型。后来,有人提出了这种转换到底是否合理的质疑 - 最后,
ECMAScript
的解决方案就是提供两组操作符:- 相等和不相等:先转换再比较
- 全等和不全等:仅比较而不转换
- 相等(
==
)和不相等(!=
)在转换不同的数据类型时,遵循下列基本规则:- 如果有一个操作数是布尔值,则先将其转换为数值;(这也是为什么
a = true
不行的原因) - 如果有一个操作数是字符串,另一个操作数是数值,则先将字符串转换为数值
- 如果一个操作数是对象,另一个操作数不是,则调用对象的
valueOf()
方法,用得到的基本类型值按照前面的规则进行比较;**如果valueOf()
也得不到基本类型值,则会调用toString()
;**如果toString()
也得不到基本类型值,则会报错:TypeError: Cannot convert object to primitive value
- 如果有一个操作数是布尔值,则先将其转换为数值;(这也是为什么
var a = 1
if(a == 1 && ++a == 2 && ++a == 3){
console.log(1);
}