Daily-Interview-Question icon indicating copy to clipboard operation
Daily-Interview-Question copied to clipboard

第 38 题:下面代码中 a 在什么情况下会打印 1?

Open zpzxgcr opened this issue 5 years ago • 65 comments

题目如下

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);
}

zpzxgcr avatar Mar 21 '19 00:03 zpzxgcr

let a = [1,2,3];
a.toString = a.shift;
if( a == 1 && a == 2 && a == 3 ) {
  console.log(1);
}

Yanhua67 avatar Mar 21 '19 00:03 Yanhua67

这题考察的应该是类型的隐式转换,考引用类型在比较运算符时候,隐式转换会调用本类型toString或valueOf方法. 解答:

var a = {num:0};
a.valueOf = function(){
  return ++a.num
}
if(a == 1 && a == 2 && a == 3){
  console.log(1);
}

jefferyE avatar Mar 21 '19 00:03 jefferyE

这个题目考察==的隐式转换吧

利用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==1&&a==2&&a==3) 成立中看javascript的隐式类型转换

Moriarty02 avatar Mar 21 '19 01:03 Moriarty02

let a = {
    gn: (function* () {
        yield 1;
        yield 2;
        yield 3;
    })(),
    valueOf() {
        return this.gn.next().value;
    }
};

win7killer avatar Mar 21 '19 03:03 win7killer

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;
	}
    }
});

win7killer avatar Mar 21 '19 04:03 win7killer

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;
    }
});

jjeejj avatar Mar 21 '19 05:03 jjeejj

一开始没转过来,群里老哥提了一声才想到这个方向

var a = Object.create({
    count: 0,
    valueOf: function() {
        return ++this.count;
    }
});

if (a == 1 && a == 2 && a == 3) {
    console.log(1);
}

HankXu avatar Mar 21 '19 14:03 HankXu

第一反应想到的是a = console.log(1)😂😂

XinJack avatar Mar 21 '19 14:03 XinJack

@XinJack 感觉你这个才是最优解啊,半天说不出一句话。

jiyuzhuang avatar Mar 22 '19 16:03 jiyuzhuang

@XinJack console.log() 的返回值是 undefined

RicoLiu avatar Mar 27 '19 01:03 RicoLiu

数组这个 a.join = a.shift; 没看懂啊

leehomeok avatar Mar 28 '19 01:03 leehomeok

数组这个 a.join = a.shift; 没看懂啊

把 shift 方法的引用 ,放到 a.join 上的。覆盖原来的 join 方法

jjeejj avatar Mar 28 '19 07:03 jjeejj

数组这个 a.join = a.shift; 没看懂啊

把 shift 方法的引用 ,放到 a.join 上的。覆盖原来的 join 方法

为啥a==1之后会执行join(shift)函数?

seujzhang avatar Mar 29 '19 07:03 seujzhang

@seujzhang 执行 a ==1 会进行隐式转换

jjeejj avatar Mar 30 '19 02:03 jjeejj

@seujzhang 执行 a ==1 会进行隐式转换

小白求教下,是不是这样的:在执行a==1的时候,会尝试对a进行隐式转换,此时隐式转换会调用Array的join方法,而此时join方法被shift覆盖,所以调用的实际上是shift方法,弹出1,然后相等,再弹出2相等,弹出3相等,最后console执行。

seujzhang avatar Mar 30 '19 03:03 seujzhang

这个题目考察==的隐式转换吧

利用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==1&&a==2&&a==3) 成立中看javascript的隐式类型转换

这个a.join = a.shift 是什么意思 还能这样子赋值麽。

quxww1 avatar Apr 02 '19 07:04 quxww1

第一反应想到的是a = console.log(1)😂😂

为什么总有一些让人眼前一亮的答案😂

yu910709 avatar Apr 03 '19 09:04 yu910709

对象转原始类型 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);
}

zeroone001 avatar Apr 08 '19 00:04 zeroone001

来一手另类的👋👋

Object.prototype.toString = (function () {
  var t = 1;
  return function () {
    return t++;
  }
})()
var a = {}
a == 1 && a == 2 && a == 3  // true

formattedzzz avatar Apr 08 '19 08:04 formattedzzz

var a = {
   value: 1,
   toString: function() {
     return a.value++;
   },
};
if(a == 1 && a == 2 && a == 3){
  console.log(1);
}
    

Caitingwei avatar Apr 20 '19 03:04 Caitingwei

第一反应想到的是a = console.log(1)

蔡徐坤行为-_-!!!

zhoubendong avatar Jul 12 '19 08:07 zhoubendong

第一反应想到的是a = console.log(1)joyjoy

为什么总有一些让人眼前一亮的答案

这操作属实有点优秀啊

zhoubendong avatar Jul 12 '19 08:07 zhoubendong

var a = true;

ShiJinlong1997 avatar Jul 19 '19 05:07 ShiJinlong1997

let i = 1; let a = new Proxy({},{ i:1, get(){ return ()=> this.i++ } }) console.log(a==1&&a==2&&a==3)

weblijingang avatar Jul 23 '19 07:07 weblijingang

解释一下好吗?

gengruohai avatar Jul 23 '19 10:07 gengruohai


var a = {
    i: 1,
    toString () {
        return this.i++
    }
}

if (a == 1 && a == 2 && a == 3) {
    console.log('真棒')
}

mongonice avatar Jul 23 '19 11:07 mongonice

为什么a==true不行?

Jay214 avatar Jul 27 '19 08:07 Jay214

为什么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

Jay214 avatar Jul 27 '19 09:07 Jay214

var a = {
	arr: [1,2,3],
	toString: function() {
		return  this.arr.shift();
	}
};

LastStranger avatar Jul 28 '19 00:07 LastStranger

题目如下

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);
}

我想提一点

image

anjohnlv avatar Jul 30 '19 02:07 anjohnlv

楼上这些答案已经很好了。我想请教一下在什么场景下才会应用到题目中的代码?

AlexZhong22c avatar Aug 14 '19 06:08 AlexZhong22c

楼上这些答案已经很好了。我想请教一下在什么场景下才会应用到题目中的代码?

没有使用场景,仅仅是考察==隐式转换这个知识点。

Hydroism avatar Aug 14 '19 07:08 Hydroism

突然发现js编程的乐趣~~~

llianer avatar Aug 15 '19 14:08 llianer

var a = { toString: function(){ //隐式转换,对象和数字做对比时,系统自动调用 this.index ++; return this.index; }, index:0 }

if(a ==1 && a==2 && a==3){ console.log(1) }

jianfeng418 avatar Sep 06 '19 07:09 jianfeng418

// 使用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

aeolusheath avatar Oct 11 '19 04:10 aeolusheath

第一反应想到的是a = console.log(1)😂😂

JavaScript 的乐趣就在于此 💯

smalike avatar Nov 28 '19 09:11 smalike

var a = ?;
if(a == 1 && a == 2 && a == 3){
  console.log(1);
}

yygmind avatar Dec 16 '19 03:12 yygmind

看到答案瞬间懵逼... 这个东西反常识,写代码单元测试的人直接吐血...

whosesmile avatar Mar 03 '20 11:03 whosesmile

数组这个 a.join = a.shift; 没看懂啊

数组隐式转换成字符串之前会执行一次join操作-> a.valueOf().join().toString()

captain-xu avatar Mar 04 '20 02:03 captain-xu

现在都推===和typescript了,还在考这些垃圾特性...

TaylerTao avatar Mar 10 '20 10:03 TaylerTao

现在都推===和typescript了,还在考这些垃圾特性...

哈哈哈哈

fireairforce avatar Mar 10 '20 11:03 fireairforce

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-------')

gylgyl avatar Apr 02 '20 03:04 gylgyl

https://blog.csdn.net/itcast_cn/article/details/82887895

cMYour avatar Apr 07 '20 04:04 cMYour

数组这个 a.join = a.shift; 没看懂啊

如何a是Array,a==1 会自动数据类型的转换,也就是调用a.join方法,而a.shift是deleteArray的第一元素并返回delete的元素,understand?

ihoneys avatar Apr 14 '20 06:04 ihoneys

来个骚的

var a = new Number()
a.valueOf = (a=>()=>a++)(1)
if ( a == 1 && a == 2 && a == 3 ) {
  console.log('1');
}

qimiaowan avatar Jun 06 '20 07:06 qimiaowan

var a = 1;
if(!(a == 1 && a == 2 && a == 3)){
 	console.log(1);
}

ptylll avatar Jun 10 '20 08:06 ptylll

@XinJack console.log() 的返回值是 undefined

但也达到了打印 1 的目的啊

cutie6 avatar Jun 15 '20 08:06 cutie6

@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方法,

jackchang2015 avatar Jul 14 '20 07:07 jackchang2015

let i = 0
Object.defineProperty('window', 'a', {
  get:()=>{
     return ++i
 }
}

zengkaiz avatar Jul 22 '20 09:07 zengkaiz

第一次访问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.

weblijingang avatar Jul 22 '20 09:07 weblijingang

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);
};

jackchang2015 avatar Jul 30 '20 09:07 jackchang2015

来一手另类的👋👋

Object.prototype.toString = (function () {
  var t = 1;
  return function () {
    return t++;
  }
})()
var a = {}
a == 1 && a == 2 && a == 3  // true

覆盖原型还是不太好

MrLeihe avatar Apr 22 '21 05:04 MrLeihe

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);
}

这样不香嘛

DemonKHH avatar Apr 25 '21 12:04 DemonKHH

    let times = 0;
    var a = {
      [Symbol.toPrimitive]: function () {
        return ++times;
      }
    };
    if (a == 1 && a == 2 && a == 3) {
      console.log(1);
    }

zhelingwang avatar May 08 '21 09:05 zhelingwang

最先想到的是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);
}

Y-J-H avatar May 30 '21 15:05 Y-J-H

var a = (function b(num){
  b.valueOf=function(){return ++num}
  return b
})(0)

nxt-hj avatar Jul 16 '21 09:07 nxt-hj

为什么a==true不行?

Boolean和其他类型比较,先被转换为Number,true被转换成 1

Ha0ran2001 avatar Aug 19 '21 11:08 Ha0ran2001

数组这个 a.join = a.shift; 没看懂啊

如何a是Array,a==1 会自动数据类型的转换,也就是调用a.join方法,而a.shift是deleteArray的第一元素并返回delete的元素,understand?

@ihoneys 啊?隐式类型转换还会调用 join 方法,我还以为就 toString 和 valueOf 呢,还有就是那个 拆箱时ToPrimitive,还会调用哪些方法?

Ha0ran2001 avatar Aug 19 '21 11:08 Ha0ran2001

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 啊

qinyakang avatar Aug 30 '21 10:08 qinyakang

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;
    }
});

LeeRayno avatar Sep 05 '21 14:09 LeeRayno

第一反应想到的是a = console.log(1)😂😂

这都没有进 if 语句啊😂

tchen-l avatar Sep 10 '21 02:09 tchen-l

(京东)下面代码中 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);
}
  1. 确定两个变量是否相等是编程中的一个非常重要的操作
    • 在比较字符串、数值和布尔值的相等性时,问题还比较简单;但在涉及到对象的比较时,问题就变得复杂了
    • 最早的ECMAScript中的相等和不等操作符会在执行比较之前,先将对象转换成相似的类型。后来,有人提出了这种转换到底是否合理的质疑
    • 最后,ECMAScript的解决方案就是提供两组操作符:
      • 相等不相等:先转换再比较
      • 全等不全等:仅比较而不转换
  2. 相等(==)和不相等(!=)在转换不同的数据类型时,遵循下列基本规则:
    • 如果有一个操作数是布尔值,则先将其转换为数值;(这也是为什么a = true不行的原因)
    • 如果有一个操作数是字符串,另一个操作数是数值,则先将字符串转换为数值
    • 如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型值按照前面的规则进行比较;**如果valueOf()也得不到基本类型值,则会调用toString();**如果toString()也得不到基本类型值,则会报错:TypeError: Cannot convert object to primitive value

Yuweiai avatar Jul 13 '22 05:07 Yuweiai

var a = 1
if(a == 1 && ++a == 2 && ++a == 3){
  console.log(1);
}

Lete114 avatar Jul 21 '22 07:07 Lete114