JavaScript常用基础知识

hoisting

http://openwares.net/js/javascript_declaration_hoisting.html

map、reduce

练习:不要使用JavaScript内置的parseInt()函数,利用map和reduce操作实现一个string2int()函数:

return [].slice.call(s).map(function(x){return x/1}).reduce(function(x, y){return x*10 + y})

JS隐式转换
Javascript 在遇到算数运算符(-*/%)的时候会在运算之前将参与运算的双方转换成数字。
注意+加号特殊哦~

练习:希望利用map()把字符串变成整数

var arr = ['1', '2', '3'];
var r;

r = arr.map(parseInt);

但是结果却是[1, NaN, NaN]
参考Array.prototype.map
原因是:

arr.map(callback[, thisArg])

Parameters

  • callback
    Function that produces an element of the new Array, taking three arguments:
    -- currentValue
    The current element being processed in the array.也就是array中需要处理的元素
    -- index
    The index of the current element being processed in the array.上面那个元素在array中的index
    -- array
    The array map was called upon.
  • thisArg
    Optional. Value to use as this when executing callback. Default value is the Window object

callback函数传递三个参数currentValue, index,array,而ParseInt需要两个参数,PareseInt会把map传过来的第二个参数index 0,1,2作为数制参数十进制,一进制,二进制,因此1被转为1 ,2和3 因为不符合一进制,二进制所以返回NaN

filter

filter也是一个常用的操作,它用于把Array的某些元素过滤掉,然后返回剩下的元素。
和map()类似,Array的filter()也接收一个函数。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。
例如,把一个Array中的空字符串删掉,可以这么写:

var arr = ['A', '', 'B', null, undefined, 'C', '  '];
var r = arr.filter(function (s) {
    return s && s.trim(); // 注意:IE9以下的版本没有trim()方法
});
r; // ['A', 'B', 'C']

arguments

JavaScript还有一个免费赠送的关键字arguments,它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数。即使函数不定义任何参数,还是可以拿到参数的值:

function abs() {
    if (arguments.length === 0) {
        return 0;
    }
    var x = arguments[0];
    return x >= 0 ? x : -x;
}

abs(); // 0
abs(10); // 10
abs(-9); // 9

实际上arguments最常用于判断传入参数的个数。你可能会看到这样的写法:

// foo(a[, b], c)
// 接收2~3个参数,b是可选参数,如果只传2个参数,b默认为null:
function foo(a, b, c) {
    if (arguments.length === 2) {
        // 实际拿到的参数是a和b,c为undefined
        c = b; // 把b赋给c
        b = null; // b变为默认值
    }
    // ...
}

要把中间的参数b变为“可选”参数,就只能通过arguments判断,然后重新调整参数并赋值。
例子:
实现函数useArguments,返回所有调用参数相加后的结果。
你可能会酱紫写。但这是错的!

function useArguments() {
    return arguments.reduce(function(x, y){
        return x+y;
    })
}

注意:arguments类似Array但它不是一个Array,所以它的原型上没有reduce方法,我们要做的就是让arguments来调用Array.prototype上的方法(用到call或者apply),或者干脆把arguments变为数组。
如何把一个伪数组转变成真正的数组呢?

Array.prototype.slice.call(arguments)

我们可以这样写

function useArguments() {
    return Array.prototype.slice.call(arguments).reduce(function(x,y){
        return x+y;
    })
}
//或者
function useArguments() {
    return [].slice.call(arguments).reduce(function(x,y){
        return x+y;
    })
}

或者让arguments来调用Array.prototype上的方法。

function useArguments() {
    return [].reduce.call(arguments, function(x,y){
        return x+y;
    })
}

因为slice,reduce都是Array.prototype上的方法,用call或者apply来改变当前对象为arguments再调用即可。

PS: concat函数用于连接两个数组,返回新的连接好的数组,而不会改变原数组。

函数的长度

函数的长度也就是函数的length属性,指的是函数的形参的个数,不是传入的参数个数哦。

function test1(){
    console.log(test1.length);  
}
test1(a,b,c); // 0

柯里化(currying)

柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且接受余下的参数且返回结果。
题目描述
已知 fn 为一个预定义函数,实现函数 curryIt,调用之后满足如下条件:
1、返回一个函数 a,a 的 length 属性值为 1(即显式声明 a 接收一个参数)
2、调用 a 之后,返回一个函数 b, b 的 length 属性值为 1
3、调用 b 之后,返回一个函数 c, c 的 length 属性值为 1
4、调用 c 之后,返回的结果与调用 fn 的返回值一致
5、fn 的参数依次为函数 a, b, c 的调用参数

var fn = function (a, b, c) {return a + b + c}; 
curryIt(fn)(1)(2)(3); //6

caller和callee

答案:(目前不太懂,貌似不让用callee属性)

function curryIt(fn) {
     //获取fn参数的数量
     var n = fn.length;
     //声明一个数组args
     var args = [];
     //返回一个匿名函数
     return function(arg){
         //将curryIt后面括号中的参数放入数组
         args.push(arg);
         //如果args中的参数个数小于fn函数的参数个数,
         //则执行arguments.callee(其作用是引用当前正在执行的函数,这里是返回的当前匿名函数)。
         //否则,返回fn的调用结果
         if(args.length < n){
            return arguments.callee;
         }else return fn.apply("",args);
     }
 }

Number.toString()方法

Number类型的toString()方法比较特殊,有默认模式和基模式两种。

//默认模式的例子:
var num1 = 10;
var num2 = 10.0;
alert(num1.toString());//输出"10"
alert(num2.toString());//输出"10"
//无论你用什么表示法声明数字,默认模式只是按十进制返回。
 
//基模式的例子:
var num1 = 10;
alert(num1.toString(2));//输出1010
alert(num1.toString(8));//输出12
alert(num1.toString(16));//输出A

全局对象的parseInt()方法和parseFloat()方法

parseInt() 函数可解析一个字符串,并返回一个整数。
1、解析字符串,直到不能解析为止
2、进制转化中,解析字符串,直到不能解析为止

document.write(parseInt("123") + "
"); //123 document.write(parseInt("1abc23") + "
"); //1 document.write(parseInt("123abc") + "
"); //123 document.write(parseInt("abc") + "
"); //NaN document.write(parseInt("100",2) + "
"); //4,以二进制形式解析 document.write(parseInt("123",2)); //1,因为2、3不能解析

parseFloat

二进制转换

题目:将给定数字转换成二进制字符串。如果字符串长度不足 8 位,则在前面补 0 到满8位。

function convertToBinary(num) {
    var tmp = num.toString(2).split('');
    while(tmp.length < 8){
        [].unshift.call(tmp, 0)
        //tmp.unshift(0);
    }
    return tmp.join('');
}

Array.unshfit()

unshift()方法可向数组的开头添加一个或更多元素,并返回新的长度请注意,unshift() 方法不创建新的创建,而是直接修改原有的数组。

String.split()

split()方法用于把一个字符串分割成字符串数组。这样才能通过call使用数组原型链上的方法啊。

Array.join()

Array.join执行的操作与String.split()执行的操作是相反的。join() 方法用于把数组中的所有元素放入一个字符串

Array.slice()

slice(0,-1)如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。http://www.w3school.com.cn/jsref/jsref_slice_array.asp

Array.splice()

splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。该方法会改变原始数组
http://www.w3school.com.cn/jsref/jsref_splice.asp

arrayObject.splice(index,howmany,item1,.....,itemX)

splice() 方法可删除从 index 处开始的零个或多个元素,并且用参数列表中声明的一个或多个值来替换那些被删除的元素。
如果从 arrayObject 中删除了元素,则返回的是含有被删除的元素的数组

Number.toFixed()

精确小数到多少位http://www.w3school.com.cn/jsref/jsref_tofixed.asp

遍历属性

function iterate(obj) {
   var result = [];
   for (var key in obj){
       if(obj.hasOwnProperty(key)){
           result.push(key+": "+obj[key])
       }
   }
    return result;
}

几条规则

  • 不要使用new Number()new Boolean()new String()创建包装对象;
  • parseInt()parseFloat()来转换任意类型到number;
  • String()来转换任意类型到string,或者直接调用某个对象的toString()方法;
  • 通常不必把任意类型转换为boolean再判断,因为可以直接写if (myVar) {...};
  • typeof操作符可以判断出number、boolean、string、function和undefined;
  • 判断Array要使用Array.isArray(arr)
  • 判断null请使用myVar === null
  • 判断某个全局变量是否存在用typeof window.myVar === 'undefined'
  • 函数内部判断某个变量是否存在用typeof myVar === 'undefined'

任何对象都有toString()方法吗?null和undefined就没有!确实如此,这两个特殊值要除外,虽然null
还伪装成了object类型。
number对象调用toString()报SyntaxError:

123.toString(); // SyntaxError

遇到这种情况,要特殊处理一下:

123..toString(); // '123', 注意是两个点!(123).toString(); // '123'

不要问为什么,这就是JavaScript代码的乐趣!

Array中的sort()

如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序。要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。

//请填充代码,使mySort()能使传入的参数按照从小到大的顺序显示出来。
function mySort() {
    var tags = new Array();//使用数组作为参数存储容器
    // 请补充你的代码
    return tags;//返回已经排序的数组
}
 
var result = mySort(50,11,16,32,24,99,57,100);/传入参数个数不确定
console.info(result);//显示结果

如果只是简单的添加了这句

tags = [].slice.call(arguments).sort();

输出的结果为[100, 11, 16, 24, 32, 50, 57, 99],100居然排在了最前面,因为sort默认是按照字符编码的顺序进行排序的。

如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:
a 小于 b,在排序后的数组中** a 应该出现在 b 之前,则返回一个小于 0 的值**。
若 a 等于 b,则返回 0。
若 a 大于 b,则返回一个大于 0 的值。

//正确代码
tags = Array.prototype.slice.call(arguments);
tags.sort(function(a,b){return a-b;});

升序:则参数方程返回小于0;降序:则返回值大于0;

js跨域

http://www.cnblogs.com/2050/p/3191744.html

事件代理

//兼容浏览器版本差异
function addEvent(element, event, listener) {
    if (element.addEventListener) {
        element.addEventListener(event, listener, false);
    }
    else if (element.attachEvent) {
        element.attachEvent("on" + event, listener);
    }
    else {
        element["on" + event] = listener;
    }
}

//事件代理
function delegateEvent (element, tag, eventName, listener){
    addEvent(element, eventName, function(e){
       //这里的参数e就是前面那个event参数的对象,自动传入
        e = e || window.event;
        var target = e.target || e.srcElement;
        console.log("event", e);
        //event:  click { target: 

你可能感兴趣的:(JavaScript常用基础知识)