-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
如何让 (a == 1 && a == 2 && a == 3) 的值为true? #9
Comments
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 = { value : 0 }; |
const a = { |
var value = 0; |
!(a == 1 && a == 2 && a == 3) |
let a = { |
1.const a = { |
== 最大的特点在于允许进行类型转换,对于对象的转换会进行toPrimitive操作,也就是先调用valueOf方法如果不能返回基本类型的值就调用toString方法 var a = {
valueOf: (function() {
var temp = 1; // 使用闭包来保存这个变量
return function() {
return temp++;
}
}())
} |
var a = { |
var a = [1, 2, 3] 或者 |
let a = { |
不太会,所以百度了下, --感谢作者,感谢小姐姐 |
== 运算符会进行隐式转换。
const a = {
i: 1,
// valueOf 也可达到相同效果
toString: function () {
return a.i++;
}
}
a == 1 && a == 2 && a == 3; // true
var a = [1,2,3];
a.join = a.shift;
a == 1 && a == 2 && a == 3; // true
let a = {
[Symbol.toPrimitive]: ((i) => () => ++i) (0)
};
a == 1 && a == 2 && a == 3; // true
var val = 0;
Object.defineProperty(window, 'a', {
get: function() {
return ++val;
}
});
a == 1 && a == 2 && a == 3; // ture
var i = 0;
with({
get a() {
return ++i;
}
}) {
a == 1 && a == 2 && a == 3; // true
} 参考: |
你这个也是一道经典的面试题 |
`` var i = 1; a.valueOf = function(){ return i++; console.log(a == 1 && a == 2 && a == 3) ---> true `` |
let num=0; |
|
对象形式这种是通过 隐式转换时调用
var a = {
v:1,
toString(){
console.log('string');
return this.v++
},
}
if(a == 1 && a == 2 && a==3){
console.log('成功')
}
var a = {
v:1,
valueOf(){
console.log('string');
return this.v++
},
}
if(a == 1 && a == 2 && a==3){
console.log('成功')
}
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('成功')
} 注意:对象隐式转换成基本类型时,如果 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('成功')
} 总结这里除了 |
== 会将左右两边的值转化成相同的原始类型,然后再去比较他们是否相等。
|
补充一种(今天刚刚get到的): |
var a=1; |
var num= 1 |
var a = { |
const a = { value: 0 }a.valueOf = function () { == 在js 中 会发生类型转换 ===全等择不会发生强转== 会把左右两边的值 转化为相同的原始数据类型然后在去比较他们是否相当 === 全等下不会执行 valueof 此时就可以 用到Object.defineProperty 因为get 和 set是可以通过"."操作符调用的方法var v = 1;Object.defineProperty(window,'a',{ |
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
|
1. 利用隐式转换规则
因此可以推测 a 是复杂数据类型,JS 中复杂数据类型只有
如以下代码,我们可以清楚的看出优先调用的是 let obj = {
[Symbol.toPrimitive]() {
return 100;
},
valueOf() {
return 200;
},
}
console.log(obj == 100);//true 那么对于这道题,只要 let a = {
[Symbol.toPrimitive]: (function() {
let i = 1;
//闭包的特性之一:i 不会被回收
return function() {
return i++;
}
})()
}
console.log(a == 1 && a == 2 && a == 3); //true 前面我们说了在没有部署 let a = {
valueOf: (function() {
let i = 1;
//闭包的特性之一:i 不会被回收
return function() {
return i++;
}
})()
}
console.log(a == 1 && a == 2 && a == 3); //true 另外一种调用 2. 利用数据劫持重写 使用 let i = 1;
Object.defineProperty(window, 'a', {
get: function() {
return i++;
}
});
console.log(a == 1 && a == 2 && a == 3); //true ES6 新增了 3. 重写数组的
|
对于这道题的理解和考察的知识点如下; } |
const a = [1, 2, 3]; |
var a = { |
首先这一题涉及的知识点1:==和===的区别
|
一、利用隐式转换原则
JavaScript的数据类型包括两种,基础数据类型(原始值)和复杂数据类型(对象值)
==两个等号时,当==左右两边数据类型不一致时,会发生隐式转换,所以基础数据类型肯定无法实现 console.log(a==1 && a==2 &&a==3); // true,考虑利用复杂数据类型 object |
引用了这篇文章
|
Proxy 形式实现: const a = new Proxy({}, {
v: 1,
get: function () {
return () => this.v++;
}
});
console.log(a == 1 && a == 2 && a == 3); // true |
这种题目好像没碰到过,这下长见识了
我看了小伙伴其他的方法还是不理解 |
可以看看我的那条答案,写得比较详细了~ |
手动点赞~ |
首先,在JS中,宽松匹配 ==会先将左右两边的值转化成相同的原始类型,然后再去比较他们是否相等。
|
当对象进行类型转换时,先执行valueOf() 函数,如果没有则执行toString()函数进行类型转换。
艳姐,不知道这次是否能明白 可以试着把 valueOf 函数注释掉,在执行看一下效果 |
想用proxy结果实验了好久没成功,只能换个方式了 |
可以写在代码块中,不然会默认变成加粗。 |
!(a == 1 && a == 2 && a == 3) 取反 |
let a = { |
O(∩_∩)O哈哈 |
偷懒啦~~~被我发现了~ |
首先要解答这道题,要先搞懂
|
此题目的答案可以分为三大类: 1. 类型转换时的劫持首先我们要知道,在 JS 中类型转换只有三种情况,分别是:
转换为原始类型对象在转换类型的时候,会执行原生方法ToPrimitive。 其算法如下:
当然,我们可以通过重写 所以以此定义我们可以有以下四种答案: var a = {
arr: [3, 2, 1],
valueOf () {
console.group('valueOf')
console.log(this.arr)
console.groupEnd('valueOf')
return this.arr.pop()
}
}
if (a == 1 && a == 2 && a == 3) {
console.log('biu')
}
var b = {
arr: [3, 2, 1],
toString () {
console.group('toString')
console.log(this.arr)
console.groupEnd('toString')
return this.arr.pop()
}
}
if (b == 1 && b == 2 && b == 3) {
console.log('biu')
}
var c = {
arr: [3, 2, 1],
[Symbol.toPrimitive] () {
console.group('Symbol.toPrimitive')
console.log(this.arr)
console.groupEnd('Symbol.toPrimitive')
return this.arr.pop()
}
}
if (c == 1 && c == 2 && c == 3) {
console.log('biu')
}
var d = [1, 2, 3]
d.join = d.shift
if (d == 1 && d == 2 && d == 3) {
console.log('biu')
} 鱼头注:事实上,这四种可以算是同一种。关于最后一种,我们可以来看看ECMA中的
2. 对
|
let num = 1
Object.defineProperty(window, 'a', {
get() {
return num++
}
}) |
|
const a = { value: 0 } == 在js 中 会发生类型转换 ===全等择不会发生强转 === 全等下不会执行 valueof 此时就可以 用到Object.defineProperty 因为get 和 set是可以通过"."操作符调用的方法 |
var aᅠ = 1; |
let a = { |
let a = { |
如何让a === 1 && a === 2 && a === 3的值为truetoStringlet obj = {
a:1,
toString() {
this.a ++;
}
}
if(a === 1 && a === 2 && a === 3) {
console.log('success')
} valueOflet obj = {
a:1,
valueOf() {
this.a ++;
}
}
if(a === 1 && a === 2 && a === 3) {
console.log('success')
} [Symbol.toPrimitive]let obj = {
a:1,
[Symbol.toPrimitive]() {
this.a ++;
}
}
if(a === 1 && a === 2 && a === 3) {
console.log('success')
} Object.definePropertylet a= 1
Object.defineProperty(window, 'a', {
get() {
return a++
}
})
if(a === 1 && a === 2 && a === 3) {
console.log('success')
} 修改数组join方法var a = [1,2,3];
a.join = a.shift;
if(a === 1 && a === 2 && a === 3) {
console.log('success')
} |
这个答案用了不可见字符 \uffa0 作为变量名,过于取巧了 |
No description provided.
The text was updated successfully, but these errors were encountered: