JavaScript 44 Puzzlers

http://mp.weixin.qq.com/s?__biz=MzAxODE2MjM1MA==&mid=2651550987&idx=1&sn=f7a84b59de14d0b99d5e12a265d55fd2&scene=0#wechat_redirect

http://mp.weixin.qq.com/s?__biz=MzAxODE2MjM1MA==&mid=2651550991&idx=1&sn=ed60b424de47cceb2b81e7df40b57efa&scene=0#wechat_redirect

http://javascript-puzzlers.herokuapp.com/

/*44 javascript puzzlers
http://javascript-puzzlers.herokuapp.com/

// 001
var res = ['1','2','3'].map(parseInt);
console.log(res);// 输出结果为:[1,NaN,NaN]
// 输出结果为:[parseInt('1',0),parseInt('2',1),parseInt('3',2)]

function foo1(){ // 查看传入的参数都是啥;
    var l = arguments.length;
    console.log('arguments begin:');
    for(var i=0;i<l;i++){
        console.log(arguments[i]);
    }
    console.log('arguments end;');
}
var res2 = ['1','2','3'].map(foo1);

// map方法会给原数组中的每一个元素都按顺序调用一次callback函数;
// callback函数会被传入3个参数:数组元素,元素索引,原数组本身;

var a = 'global a';
function foo2(){
    console.log(this.a);
}

foo2(); // 直接调用会输出 'global a'

var obj = {};
obj.a = 'object a';

var res = [1,2,3].map(foo2,obj); // 会输出三个'object a'
// map方法传入一个回调函数,并且传入一个回调函数中的this对象;
console.log(res); // [undefined, undefined, undefined]


// 002
var res = [typeof null, null instanceof Object];
console.log(res); // ['object',false]
// js共有6种数据类型 Undefined,String,Number,Boolean,Object,Null
// 每种对应的typeof为'undefined','string','number','boolean','object','object'
// Function 不是数据类型,但是typeof Function 返回 'function'

// JavaScript instanceof运算符代码
// http://www.ibm.com/developerworks/cn/web/1306_jiangjj_jsinstanceof/
function instance_of(L,R){ // L表示左表达式,R表示右表达式
    var O = R.prototype; // 取R的显示原型
    L = L.__proto__; // 取L的隐式原型
    while(true){
        if(L === null){
            return false;
        }
        if(O === L){ // 这里重点:当O严格等于L时,返回true
            return true;
        }
        L = L.__proto__;
    }
}

function Aoo(){}
function Foo(){}
Foo.prototype = new Aoo(); // JavaScript原型继承
var foo = new Foo();
console.log(foo instanceof Foo); // true
console.log(foo instanceof Aoo); // true
console.log(Object instanceof Object); //true
console.log(Function instanceof Function); //true
console.log(Number instanceof Number); // false
console.log(String instanceof String); // false
console.log(Function instanceof Object); // true
console.log(Foo instanceof Function); // true
console.log(Foo instanceof Foo); // false

// 003
//var res = [[3,2,1].reduce(Math.pow),[].reduce(Math.pow)]; // 这一行就会直接报 TypeError,不能对空数组调用reduce方法;
//console.log(res);

//var res = [3,2,1].reduce(Math.pow);
//console.log(res); // 输出9 , Math.pow(3,2),Math.pow(9,1)

function foo1(){
    var l = arguments.length;
    console.log('arguments begin:');
    for(var i=0;i<l;i++){
        console.log(arguments[i]);
    }
    console.log('arguments end:');
}
//var res = ['a','b','c'].reduce(foo1);
// reduce中的回调函数会获得四个参数: 初始值(或者上一次回调函数的返回值,没有返回值就是undefined),当前值,当前值索引,原数组
// 如果没有初始值,就会把数组第一个值作为初始值;
//var res = ['a','b','c'].reduce(foo1,'A');

//var obj = {};
//var res = [1,2,3].reduce(obj); // 如果回调函数不是函数,也会直接抛出TypeError异常

// 004

var val = 'smtg';
console.log('Value is ' + (val==='smtg')?'Something':'Nothing');
// + 优先级 大于 ? , 等价于 'Value is true'?'Something':'Nothing'



// 005

var name='World';
(function(){
    if(typeof name === 'undefined'){
        var name = 'Jack';
        console.log('Goodbye '+name); 
    }else{
        console.log('Hello '+name);
    }
})();

(function(){
    var a;
    if(typeof a === 'undefined'){
        var name = 'Jack';
        console.log('Goodbye '+name); 
    }else{
        console.log('Hello '+name);
    }
})();

(function(){
    var a='';
    if(typeof a === 'undefined'){
        var name = 'Jack';
        console.log('Goodbye '+name); 
    }else{
        console.log('Hello '+name); // 这个变量的确被提升了;Hoisting
    }
})();

(function(){
    var a='';
    if(typeof a === 'undefined'){
        var name = 'Jack';
        console.log('Goodbye '+name); 
    }else{
        console.log('Hello '+name1); //  这个就会报异常,name1 is not defined
    }
})();



// 006

var END = Math.pow(2,53); // 9007199254740992
var START = END - 100;
var count = 0;

//for(var i= START;i>> 0;
    if (typeof fun !== 'function') {
      throw new TypeError();
    }

    var res = [];
    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
    for (var i = 0; i < len; i++) {
      if (i in t) { // 首先判断是否在数组内;
        var val = t[i];

        // NOTE: Technically this should Object.defineProperty at
        //       the next index, as push can be affected by
        //       properties on Object.prototype and Array.prototype.
        //       But that method's new, and collisions should be
        //       rare, so use the more-compatible alternative.
        if (fun.call(thisArg, val, i, t)) {
          res.push(val);
        }
      }
    }

    return res;
  };
}

// 008
var one = 0.1;
var two = 0.2;
var six = 0.6;
var eight = 0.8;

var res = [two-one==one, eight-six==two];
console.log(res); // [true,false]

var arr = [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9];
for(var i=0;i<9;i++){
    for(var j=0;j4? console.log(arr[i]+'+'+arr[j]+'='+(arr[i]+arr[j])):0;
        (arr[i]-arr[j]+'').length>4? console.log(arr[i]+'-'+arr[j]+'='+(arr[i]-arr[j])):0;
    }
}

// JavaScript中计算精度丢失的问题 IEEE754  http://rockyee.iteye.com/blog/891538
//   0.00011001100110011001100110011001100110011001100110011001    
//+  0.00110011001100110011001100110011001100110011001100110011  
// =  0.01001100110011001100110011001100110011001100110011001100    
// 转换成10进制之后得到:0.30000000000000004 


// 009

function showCase(value){
    switch(value){
    case 'A':
        console.log('Case A');
        break;
    case 'B':
        console.log('Case B');
        break;
    case undefined:
        console.log('undefined');
        break;
    default:
        console.log('Do not know');
    
    }

}

showCase(new String('A'));
showCase('B');
// switch是严格比较, String实例和字符串是不一样的;
console.log(typeof 'A');
console.log(typeof new String('A'));
console.log('A' === new String('A'));

// 010

function showCase2(value){
    switch(value){
    case 'A':
        console.log('Case A');
        break;
    case 'B':
        console.log('Case B');
        break;
    case undefined:
        console.log('undefined');
        break;
    default:
        console.log('Do not know!');
    
    }
}

showCase2(String('A'));

// String(x) 并不创建对象;
console.log(typeof 'A');
console.log(typeof  String('A'));
console.log('A' ===  String('A'));

// 011

function isOdd(num){
    return num%2 == 1;
}
function isEven(num){
    return num%2 == 0;
}
function isSane(num){
    return isEven(num)||isOdd(num);
}
var values = [7,4,'13',-9,Infinity];
var res = values.map(isSane);
console.log(values);
console.log(res);

// 012
var res1 = parseInt(3,8);
var res2 = parseInt(3,2);
var res3 = parseInt(3,0);
console.log(res1);
console.log(res2);
console.log(res3);

// 013

var res  = Array.isArray(Array.prototype);
console.log(res);
// Array.prototype => []


// 014

var a=[0];
if([0]){
    console.log(a==true);
}else{
    console.log('wut');
}

console.log(a==true); // false
console.log(a==false); // true
var b=[0,1];
console.log(b==true); // false
console.log(b==false); // false
if(b){
    console.log('b is true');
}else{
    console.log('b is false');
}

// JavaScript-Equality-Table

var obj = {}; // 图片上面有表示
if(obj){
    console.log('obj if true');
}else{
    console.log('obj if false');
}

if(a===b){ // undefined === undefined
    var a = 'a';
    var b = 'b';
    console.log('a===b');
}else{
    console.log('a!=b');
}

// JavaScript-Equality-Table 记忆:括号不恒等,非数(NaN)空象({})恒不等;

// 015
var res = ([] == []);
console.log(res);
// 见上图


// 016

var res1 = '5'+3;
var res2 = '5'-3;

console.log(res1);
console.log(res2);

console.log(typeof res1);
console.log(typeof res2);

var res3 ='5'-'3';
console.log(res3);
console.log(typeof res3); // 减号尽可能把操作数变为数字;

var res4 = 'a' - '1';        // 就连NaN 的typeof也是数字
console.log(res4);            // NaN
console.log(typeof res4); // number

// 017
var res = 1+-+++-+1; // 系统提示错误,Uncaught ReferenceError:
console.log(res);

+1; // ok
-+1; // OK
+-+1; // OK
++-+1; // Uncaught ReferenceError;
1+-+-+1; // 2 OK 

++1;// Uncaught ReferenceError
var i=1;
++i;// 2
++-+i ; // Uncaught ReferenceError




// 018
var ary = Array(3);
ary[0] = 2;
var res = ary.map(function(elm){return '1';});
console.log(res); // ["1"],length = 3
var res2 = ary.map(function(elm){return elm;});
console.log(res2); // 好像是清除了空的元素 ,length = 3
console.log(ary);  // 但是这个也是 [2]没有空元素,length = 3

var ary2 = [];
ary2[0] = 0,ary2[10] = 10;
var res3 = ary2.map(function(elm) {return elm;});
console.log(res3);
console.log(ary2);
console.log(res3[10]); // 还是一样的稀疏矩阵


// Array.prototype.map 的 polyfill.

Array.prototype.map = function(callback, thisArg) {
 
        var T, A, k;
 
        if (this == null) {
            throw new TypeError(' this is null or not defined');
        }
 
        var O = Object(this);
        var len = O.length >>> 0;
        if (typeof callback !== 'function') {
            throw new TypeError(callback + ' is not a function');
        }
        if (arguments.length > 1) {
            T = thisArg;
        }
        A = new Array(len);
        k = 0;
        while (k < len) {
            var kValue, mappedValue;
            if (k in O) {
                kValue = O[k];
                mappedValue = callback.call(T, kValue, k, O);
                A[k] = mappedValue;
            }
            k++;
        }
        return A;
    };*/

 

 

 

$(function() {
    init();
});// js44function init(e) {}/*
 * 
 * 
 * // 019

function sidEffecting(ary) {
    ary[0] = ary[2];
}

function bar(a,b,c) {
    c = 10;
    console.log(arguments);
    console.log(a,b,c);
    sidEffecting(arguments);
    console.log(arguments);
    console.log(a,b,c);
    return a+b+c;
}
//var res = bar(1,1,1);
//console.log(res); // 21 

function bar2(a, b, c=3) { // 如果有默认值,就无法用arguments方式修改了;
    c = 10;
    console.log(arguments); // [1,1,1]
    console.log(a,b,c);
    sidEffecting(arguments);
    console.log(arguments); // [1,1,1]
    console.log(a,b,c);
    return a+b+c;
}
//var res2 = bar2(1,1,1);
//console.log(res2); // 12
//var res3 = bar2(1,1);
//console.log(res32); // 12

function bar3(a,b,c) { // 如果传入的参数不够,也无法用arguments方式修改;
    console.log(typeof c);
    console.log(typeof arguments[2]);
    c = 10;
    console.log(typeof c);
    console.log(arguments);
    console.log(a,b,c);
    sidEffecting(arguments);
    console.log(arguments);
    console.log(a,b,c);
    return a+b+c;
}

var res4 = bar3(1,1);
console.log(res4);

// 020

var a = 111111111111111110000, b = 1111;
      //123456789012345678901
var c = a+ b;

var a1 = 2147483647;
var a2 = Math.pow(2,53); // 可以表示的最大的数字?第6题 9007199254740992(共16位)

console.log(c); // 111111111111111110000 与数值的存储方式有关
console.log(typeof a); // number
console.log(a1+b);
console.log(a2);
console.log(a2+1); // a2+1已经不变了;但是a2+2还是会变的;

var a3 = 12345678901234567;
console.log(a3); // 12345678901234568
console.log(a3+1);


// 021

//var x = [].reverse;
//x();  // Uncaught TypeError: Array.prototype.reverse called on null or undefined

var arr = ["a","b","c"];
//console.log(arr.reverse());
var x = arr.reverse;
var res = x.call(arr);
console.log(res);
var arr1 = ["d","e","f"];
var res2 = x.call(arr1);
console.log(res2);


// 022
var res = Number.MIN_VALUE >0;
console.log(res); // true
console.log(Number.MIN_VALUE); // 5e-324,接近0,但不是负数;
console.log(Number.MAX_VALUE); // 1.7976931348623157e+308


// 023

var res = [1<2<3,3<2<1];
console.log(res); // [true,true]

var res1 = [true<3,falsec;
var res4 = a<c;
console.log(res1,res2,res3,res4);
console.log(a.toString());
console.log(a.valueOf());
console.log(a.valueOf()-b.valueOf());
console.log(!!(a.valueOf()-b.valueOf()));


// 029
var a = {}, b = Object.prototype;
var res = [a.prototype === b,Object.getPrototypeOf(a)===b];
console.log(res);
console.log(a.__proto__ === b); // true
console.log(a.prototype); // undefined
console.log(Object.getPrototypeOf(1) === Number.prototype); // true 
//console.log(1.__proto__); // 这样写会出错
// Object.getPrototypeOf(obj) 返回一个具体对象的原型


// 030

function f() {}
var a = f.prototype, b = Object.getPrototypeOf(f);
var res = (a===b);
console.log(res);
console.log(b===Function.prototype); // b is f.__proto__
var a1 = new f();
console.log(a1.__proto__ === a);

// 031

function foo() {}
var oldName = foo.name;
foo.name = "bar";
console.log(oldName, foo.name); // 函数的name不能修改

var foo2 = function (e) {}

console.log(foo2.name);  // 匿名函数的name就是一个空字符串
console.log(foo2.name === "");
foo2.name = "bar2";
console.log(foo2.name); // 匿名函数的name也不能修改



// 032
var res = "1 2 3".replace(/\d/g, parseInt);
console.log(res);

function showArgs() {
    console.group('show Args');
    var len = arguments.length;
    for(var i=0;i<len;i++){
        console.log(arguments[i]);
    }
    console.groupEnd();
}
function showArgs2(e) {
    console.log(arguments);
}
//"1 2 3".replace(/\d/g,showArgs);

// 如果replaceText为函数,对于每一个匹配的子字符串,调用该函数时带有m+3个参数,此处m是regExp中捕获的
// 左括弧的个数。第一个参数是匹配的子字符串,接下来的m个参数是查找中捕获的全部结果。第m+2个参数是在stringObj
// 中匹配出现的偏移量,而第m+3个参数为stringObj

//"1a2b3c4".replace(/(\d+)(\D+)(\d+)/g,showArgs); // 查看匹配的m个参数

// 替换模式中的子表达式
var res = "1a2b3c4d".replace(/(\d+)(\D+)/g,"$2$1"); // 数字和字母替换
console.log(res);
"1a2b3c4d".replace(/(\d+)(\D+)/g,showArgs2); // 看看匹配的结果
//"1a2b3c4d".replace(/(\d+)(\D+)/g,function($0,$1,$2){
//    console.group('show $');
//    console.log($0); // 匹配到的字符串
//    console.log($1);
//    console.log($2);
//    console.groupEnd();
//});
var res = "123a456".replace(/\D+/g,"{$&}"); // 给匹配的内容加上{}
//console.log(res);
//var res = "123a456".replace(/\D+/g,"$`"); // 匹配字符串左边的字符
//var res = "123a456".replace(/\D+/g,"$'"); // 匹配字符串右边的字符
//console.log(res);


// 033

function f() {}
var parent = Object.getPrototypeOf(f);
//console.log(f.name);
//console.log(parent.name);
//console.log(typeof eval(f.name));
//console.log(typeof eval(parent.name));

// eval() 函数可计算某个字符串,并执行其中的JavaScript代码;
function a(e) {
    console.log("this is a function");
}
eval("a"); // 就是一个函数
a;

var b = function(){}; // 匿名函数,其name是空字符串;
eval("b");
var res = eval("");
console.log(res);

// 034

var lowerCaseOnly = /^[a-z]+$/;
var res = [lowerCaseOnly.test(null),lowerCaseOnly.test()];
console.log(res);

// test方法,返回一个boolean值,它指出在被查找的字符串中是否存在模式;

var reg = /\D/g;
console.log(reg.lastIndex);
console.log(reg.test("123abc89"),reg.lastIndex);
console.log(reg.test("123abc89"));
console.log(reg.test("123abc89"));
console.log(reg.test("123abc89"),reg.lastIndex); // 如果是全局正则,注意lastIndex熟悉

// 035

var res = [,,,].join(",");
console.log(res);

//var arr = [,,,];
//console.log(arr); // []
//console.log(arr.length); // 3
//console.log(arr[0]); // undefined
//console.log(arr.join("*")); // **

var arr2 = [undefined,undefined,undefined,];
console.log(arr2);
console.log(arr2.length);
console.log(arr2[0]);
console.log(arr2.join("*")); // **

// 036

var a = {class:"Animal",name:'Fido','if':"iiff"};
console.log(a.class); // class是关键字
console.log(a['class']); // 推荐使用
console.log(a.if);
console.log(a['if']);

// 037

var a = new Date("epoch");
console.log(a); // Invalid Date
console.log(typeof a); // object
console.log(a instanceof Date); // true; a 是Date

// 038

var a = Function.length, b = new Function().length;
console.log(a===b);

console.log(Function.length); // 这个就是1
console.log(new Function("x","y","return x+y").length); // 这个表示函数的参数个数
var b = new Function("x","y","return x+y");
console.log(b(2,2));


// 039

var a = Date(0);
var b = new Date(0);
var c = new Date();
console.log([a===b, b===c, a===c]);
//console.log(a);
//console.log(b);
//console.log(c);
console.log(a==c); // 这个是相等的
console.log(Date(0));
console.log(Date(60000));
console.log(Date("a")); // 不论输入什么,输出都是 new Date();
console.log(new Date());


// 040

var min = Math.min(), max = Math.max();
console.log(min<max);

console.log(Math.min()); // Infinity
console.log(Math.max()); // -Infinity

// 041

function captureOne(re, str) {
    console.log(re,re.lastIndex);
    var match =re.exec(str);
    console.log(match);
//    console.log(match[1]);
    return match && match[1];
}

var numRe = /num=(\d+)/g,
    wordRe = /word=(\w+)/i,
    a1 = captureOne(numRe, "num=1"),
    a2 = captureOne(wordRe, "word=1"),
    a3 = captureOne(numRe, "NUM=2"),
    a4 = captureOne(wordRe, "WORD=2");
console.log([a1===a2,a3===a4]);

console.log(a1);
console.log(a2);
console.log(a3); // 有g选项,全文查找出现的所有pattern,注意其lastIndex属性;
console.log(a4);

// 042
var a = new Date("2014-03-19"),
    b = new Date(2014,03,19);
console.log([a.getDay()===b.getDay(),a.getMonth()===b.getMonth()]);

// dateObj = new Date(year,month,date[,hours[,minutes[,seconds[,ms]]]])
// month 必选项。表示月份,从0到11之间的整数(1月至12月)
// getDay方法,返回Date对象中用本地时间表示的一周中的日期值,0至6之间的整数;
// 记忆:What day is today?

// 043

if('http://gifwrapped.com/picture.jpg'.match('.gif')){
    console.log('a gif file');
}else{
    console.log('not a gif file');
}

// String.prototype.match接受一个正则,如果不是,按照 new RegExp(obj)转化,所以.不会转义

// 044

function foo(a) {
    var a;
    return a;
}

function bar(a) {
    var a = "bye";
    return a;
}

console.log([foo('hello'),bar('hello')]);

var a = "a string";
var a; // 可以定义多次;
console.log(a);


 * 
 */