Step-By-Step
Step-By-Step copied to clipboard
如何让 (a == 1 && a == 2 && a == 3) 的值为true?
var i = 1
Number.prototype.valueOf = function() {
return i++
}
var a = new Number(1)
if (a == 1 && a == 2 && a == 3) {
console.log('here')
}
{[Symbol.toPrimitive]: ((i) => () => ++i) (0)}
var aᅠ = 1; var a = 2; var ᅠa = 3; console.log(aᅠ==1 && a== 2 &&ᅠa==3)
var a = { value : 0 }; a.valueOf = function() { return this.value += 1; }; console.log(a==1 && a==2 && a==3);
const a = { i: 1, toString: function () { return a.i++; } } if(a == 1 && a == 2 && a == 3) { console.log('Hello World!'); }
var value = 0; Object.defineProperty(window,'a',{ get:function(){ return this.value += 1; } }) console.log(a== 1 && a==2 && a==3);//true
!(a == 1 && a == 2 && a == 3)
let a = { num:0, valueOf:function(){ return this.num += 1 } } let aa = (a == 1 && a == 2 && a == 3) console.log(aa)
1.const a = { i: 1, toString: function () { return a.i++; } } if(a == 1 && a == 2 && a == 3) { console.log('Hello World!'); } 2.var aᅠ = 1; var a = 2; var ᅠa = 3; if(aᅠ==1 && a== 2 &&ᅠa==3) { console.log("Why hello there!") } 3.var val = 0; Object.defineProperty(window, 'a', { get: function() { return ++val; } }); if (a == 1 && a == 2 && a == 3) { console.log('yay'); } 参考了http://web.jobbole.com/93874/
== 最大的特点在于允许进行类型转换,对于对象的转换会进行toPrimitive操作,也就是先调用valueOf方法如果不能返回基本类型的值就调用toString方法
var a = {
valueOf: (function() {
var temp = 1; // 使用闭包来保存这个变量
return function() {
return temp++;
}
}())
}
var a = { i: 0, valueOf: function() { return this.i += 1; } } if(a==1 && a==2 && a==3){ console.log('nice, 马飞~~~') }
var a = [1, 2, 3] a.join = a.shift console.log(a==1 && a==2 && a==3) 利用数组转化为字符串都会调用,Array.join
或者 var a = { value: 1, toString: function () { return this.value ++ }
let a = { value: 0, valueOf: function() { return this.value += 1; } } console.log(aᅠ==1 && a== 2 &&ᅠa==3) JS对象有toString() 和valueOf()两个方法,toString()将该对象的原始值以字符串的形式返回,valueOf()返回最适合该对象的原始值,这两个方法一般是交由JS去隐式调用,以满足不同的运算情况。 在数值运算里,会优先调用valueOf(),在字符串运算里,会优先调用toString()。 1.用运算符对对象进行转换的时候valueOf()的优先级高于toString() 2.对对象进行强字符串转换时会优先调用toString() 3.toString()方法不能对null和undefined进行字符串转换,可以用String()方法代替
不太会,所以百度了下, 有几种方法实现 1、重写Object的toString或者valueOf 2、定义"a"属性,并重写它的getter方法 3、字符编码 4、数组toString隐含调用join()方法 参考了 https://majing.io/posts/10000006051204 https://www.codercto.com/a/41494.html
--感谢作者,感谢小姐姐
== 运算符会进行隐式转换。
- Object ==操作符会尝试通过方法valueOf和toString将对象转换为其原始值(一个字符串或数字类型的值)。
const a = {
i: 1,
// valueOf 也可达到相同效果
toString: function () {
return a.i++;
}
}
a == 1 && a == 2 && a == 3; // true
- Array 对于数组对象,toString 方法返回一个字符串,该字符串由数组中的每个元素的 toString() 返回值经调用 join() 方法连接(由逗号隔开)组成。
var a = [1,2,3];
a.join = a.shift;
a == 1 && a == 2 && a == 3; // true
- Symbol Symbol对象被转为原始类型的值时,会调用 toPrimitive 方法,返回该对象对应的原始类型值。
let a = {
[Symbol.toPrimitive]: ((i) => () => ++i) (0)
};
a == 1 && a == 2 && a == 3; // true
- 修改window的get方法
var val = 0;
Object.defineProperty(window, 'a', {
get: function() {
return ++val;
}
});
a == 1 && a == 2 && a == 3; // ture
- 利用with关键字 emmm... with关键字好像很少用到
var i = 0;
with({
get a() {
return ++i;
}
}) {
a == 1 && a == 2 && a == 3; // true
}
参考:
var aᅠ = 1; var a = 2; var ᅠa = 3; console.log(aᅠ==1 && a== 2 &&ᅠa==3)
你这个也是一道经典的面试题 但是跟本题不是同一题呢~ 注意审题哦~
`` var a = new Number();
var i = 1;
a.valueOf = function(){
return i++; }
console.log(a == 1 && a == 2 && a == 3) ---> true
`` 复杂数据类型与原始数据比较时,会隐式调用toString()和valueOf(),将对象转换成原始值; 所以object用来比较时,改写toString()和valueOf()方法即可;
let num=0; Object.definedProperty(this, 'a', { get(){ return ++num } }) console.log(a == 1 && a == 2 && a == 3) // true
var i = 1
var a = new Number(1)
Number.prototype.valueOf =function() {
return i++
}
console.log(a == 1 && a == 2 && a == 3);
对象形式
这种是通过 隐式转换时调用 toString 或者 valueOf 或者 Symbol.toPrimitive (es6)的形式来转换
- toString
var a = {
v:1,
toString(){
console.log('string');
return this.v++
},
}
if(a == 1 && a == 2 && a==3){
console.log('成功')
}
- valueOf
var a = {
v:1,
valueOf(){
console.log('string');
return this.v++
},
}
if(a == 1 && a == 2 && a==3){
console.log('成功')
}
- Symbol.toPrimitive
var a = {
v:1,
//该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值
//被调用时,会接受一个字符串参数,表示当前运算的模式,一共有三种模式(number,string,default)
[Symbol.toPrimitive](h){
console.log(h);
return this.v++
}
}
if(a == 1 && a == 2 && a==3){
console.log('成功')
}
注意:对象隐式转换成基本类型时,如果 Symbol.toPrimitive 和 toString 或者 valueOf 同时存在时 会优先调用 Symbol.toPrimitive
如果 Symbol.toPrimitive 不存在时 会先调用 valueOf,如果valueOf的返回值还是一个对象时(默认情况 会返回对象本身)则再调用
toString,如果toString 返回值还是一个对象(人为定义覆盖,默认会返回[object Object]) 则抛出错误
getter 拦截
var v = 1;
Object.defineProperty(window,'a',{
get(){
return v++;
}
})
if(a == 1 && a == 2 && a==3){
console.log('成功')
}
数组对象
var a = [1,2,3];
//方法1
a[Symbol.toPrimitive] = function(){return this.shift()};
//方法2
// arr.valueOf = function(){return this.shift()}
//方法3
//a.toString = function(){return this.shift()}
//方法4
a.join = a.shift;
if(a == 1 && a == 2 && a==3){
console.log('成功')
}
对于方法4理解:a隐式转换会调用toString方法 而toString方法内部会调用 join方法

函数形式
var a = (()=>{
let n=0;
let s = ()=>1;
s.toString = ()=>++n; //这里还可以用valueOf ,Symbol.toPrimitive
return s;
})();
if(a == 1 && a == 2 && a==3){
console.log('成功')
}
总结
这里除了 getter 其他的方法 都是隐式调用了 toString 或 valueOf 或 Symbol.toPrimitive 来完成转换
== 会将左右两边的值转化成相同的原始类型,然后再去比较他们是否相等。
-
如果a是一个对象Object,在执行a==的时候首先会执行valueOf方法,如果没有valueOf方法,会执行toString方法。 const a = { value: 0 } a.valueOf = function () { return this.value += 1 } console.log( a == 1 && a == 2 && a == 3 );
-
如果a是一个数组Array,在数组转换成字符串的时候,数组toString会隐含调用join()方法 const a = [1, 2, 3]; a.join = a.shift; console.log( a == 1 && a == 2 && a ==3 );
!( a == 1 && a == 2 && a ==3 )
偷个懒~o( ̄︶ ̄)o
补充一种(今天刚刚get到的): var a console.log( (a == 1 && a == 2 && a ==3) || ture ) 持续偷懒(^o^)/~
var a=1; var a=2; var a = 3; console.log(a==1 && a==2 &&a==3);
var num= 1 Object.defineProperty("window", "a", { get(){ return num++ } })
var a = { val: 0, valueOf: function() { return this.val += 1; } } if (a == 1 && a == 2 && a == 3) {console.log('xiaoxiao');} // == 号会发生隐士类型转换,如果发现所比较的数类型不同的话就会进行转换 如果两个数一个为undefined另一个为null则直接返回true 如果一个为数字另一个为string则将string转换为Number 如果一个为Boolean另一个为Number则将Boolean转换为Number 如果一个为对象另一个为Number则将object转换为原始类型 1、首先会调用自身的valueOf,当然也会去查找原型上有没有,如果有则直接转 2、其次才会调用自身的toString方法,当然也会去原型链上查找是否存在,然后进行相应的转换 3、如果上面两个方法都没有找到那么就返回false 本题则是在考==号的隐士转换,其次是因为a要等于三个不同的数,所以自身改写函数返回不同值即可得到结果
const a = { value: 0 }
a.valueOf = function () { return this.value += 1 } console.log(a==1 && a==2 && a==3)
== 在js 中 会发生类型转换 ===全等择不会发生强转
== 会把左右两边的值 转化为相同的原始数据类型然后在去比较他们是否相当 如果输入的是个基本类型就直接返回这个类型值 如果输入是Object类型 那就先调用输入对象的valueOf()如果是基本类型的话就直接返回 如果不是在调用toSting() 是基本类型 就返回他 js 在解析a==1 时 1 是基本数据类型 所以会把a 转换为Nubmer a.valueof 覆盖的原来的valueof 被调用时 会返回1 自增+1返回自身
=== 全等下不会执行 valueof 此时就可以 用到Object.defineProperty 因为get 和 set是可以通过"."操作符调用的方法
var v = 1;
Object.defineProperty(window,'a',{ get(){ return v++; } }) a == 1 && a == 2 && a==3
let a = {
i: 1,
valueOf: function() {
return a.i++;
}
}
// == 的时候会隐形调用了 valueOf() 或者 toString()
console.log(a == 1 && a == 2 && a == 3); // true
const a = {
num: 0,
valueOf: function() {
return this.num += 1
}
};
console.log(a==1 && a==2 && a==3); // true
- 使用相等操作符,js会做强制类型转化
- 我们的对象每次调用valueOf()它的值会增加1
- (a==1 && a==2 && a==3) 当他们比较时,JavaScript会企图将对象转化成数字的类型,进行比较。
- 当要转化的是一个Object的时候,JavaScript会调用本身的valueOf()方法,这个时候就可以实现 this.num += 1
== 和 === 的区别
===不需要进行类型转换, 只有类型相同并且值相等时, 才返回true==如果两者类型不同, 则会进行隐式转换
如果对象和简单数据类型比较, 会先调用valueOf方法, 如果返回还是对象则在调用toString方法, 这时我们就可以通过 attribute 拦截实现目的
const a = {
// valueOf 也是一样
toString: (i => _ => i++ )(1)
}
console.log(a == 1 && a == 2 && a == 3);
数组调用 toString 方法, 会调用本身的join 方法
const a = [1,2,3];
// 利用shift 每次从头部截取一个值来实现
a.join = a.shift;
console.log(a == 1 && a == 2 && a == 3)
ES6 新增Symbol, 对象的Symbol.toPrimitive属性,指向一个方法。该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。
const a = {
[Symbol.toPrimitive]: (i => _ => i++ )(1)
}
console.log(a == 1 && a == 2 && a == 3)
** 如果要实现 (a === 1 && a === 2 && a === 3)为true, 这可以通过拦截getter**
const num = new Proxy({}, {
get: (i => _ => i++ )(1)
})
console.log(num.a === 1 && num.a === 2 && num.a === 3);
1.运算子是对象时候的valueOf toString 方法
const a = {
i: 0,
valueOf: function(){
return a.i++;
}
}
console.log(a==1 && a==2 && a==3); // true
如果原始类型的值与对象比较,对象会先转换成原始类型的值,转换规则,对象先调用valueOf方法,若还是对象,再调用toString方法。
2.利用数组特性
const a = [1,2,3];
a.join = a.shift;
console.log(a==1 && a==2 && a==3); // true
数组也是对象,与原始类型的值作比较,也会调用toString方法,返回一个字符串,该字符串由数组中的每个元素调用toString()再调用自身的join()方法生成。这种方法,将数组的join方法改写为shift方法。当a==1时,a调用toString()得到‘1’,再调用join即shift方法,返回1,并且删掉第一个元素,可以得到‘1’==1,以此类推。