Array.prototype.map()

map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。

let numbers = [1, 5, 10, 15];
let doubles = numbers.map((x) => {
   return x * 2;
});

// doubles is now [2, 10, 20, 30]
// numbers is still [1, 5, 10, 15]


let numbers = [1, 4, 9];
let roots = numbers.map(Math.sqrt);

// roots is now [1, 2, 3]
// numbers is still [1, 4, 9]

语法

let array = arr.map(function callback(currentValue, index, array) { 
    // Return element for new_array 
}[, thisArg])

参数

callback
生成新数组元素的函数,使用三个参数:

currentValue
callback 的第一个参数,数组中正在处理的当前元素。
index
callback 的第二个参数,数组中正在处理的当前元素的索引。
array
callback 的第三个参数,map 方法被调用的数组。
thisArg
可选的。执行 callback 函数时 使用的this 值。

返回值

一个新数组,每个元素都是回调函数的结果。

描述

map 方法会给原数组中的每个元素都按顺序调用一次  callback 函数。callback 每次执行后的返回值(包括 undefined)组合起来形成一个新数组。 callback 函数只会在有值的索引上被调用;那些从来没被赋过值或者使用 delete 删除的索引则不会被调用。

callback 函数会被自动传入三个参数:数组元素,元素索引,原数组本身。

如果 thisArg 参数有值,则每次 callback 函数被调用的时候,this 都会指向 thisArg 参数上的这个对象。如果省略了 thisArg 参数,或者赋值为 null 或 undefined,则 this 指向全局对象 。

map 不修改调用它的原数组本身(当然可以在 callback 执行时改变原数组)。

使用 map 方法处理数组时,数组元素的范围是在 callback 方法第一次调用之前就已经确定了。在 map 方法执行的过程中:原数组中新增加的元素将不会被 callback 访问到;若已经存在的元素被改变或删除了,则它们的传递到 callback 的值是 map 方法遍历到它们的那一时刻的值;而被删除的元素将不会被访问到。

用一个仅有一个参数的函数来mapping一个数字数组

下面的代码表示了当函数需要一个参数时map的工作方式。这个参数会遍历原始数组中的元素。

var numbers = [1, 4, 9];
var doubles = numbers.map(function(num) {
  return num * 2;
});

// doubles is now [2, 8, 18]
// numbers is still [1, 4, 9]

一般的 map 方法

下面的例子演示如何在一个 String  上使用 map 方法获取字符串中每个字符所对应的 ASCII 码组成的数组:

var map = Array.prototype.map
var a = map.call("Hello World", function(x) { 
  return x.charCodeAt(0); 
})
// a的值为[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

querySelectorAll 应用

下面代码展示了如何去遍历用 querySelectorAll 得到的动态对象集合。在这里,我们获得了文档里所有选中的选项,并将其打印:

var elems = document.querySelectorAll('select option:checked');
var values = Array.prototype.map.call(elems, function(obj) {
  return obj.value;
});

反转字符串

var str = '12345';
Array.prototype.map.call(str, function(x) {
  return x;
}).reverse().join(''); 

// Output: '54321'
// Bonus: use '===' to test if original string was a palindrome

兼容旧环境(Polyfill)Edit

map 是在最近的 ECMA-262 标准中新添加的方法;所以一些旧版本的浏览器可能没有实现该方法。在那些没有原生支持 map 方法的浏览器中,你可以使用下面的 Javascript 代码来实现它。所使用的算法正是 ECMA-262,第 5 版规定的。假定ObjectTypeError, 和 Array 有他们的原始值。而且 callback.call 的原始值也是 Function.prototype.call

// 实现 ECMA-262, Edition 5, 15.4.4.19
// 参考: http://es5.github.com/#x15.4.4.19
if (!Array.prototype.map) {
  Array.prototype.map = function(callback, thisArg) {

    var T, A, k;

    if (this == null) {
      throw new TypeError(" this is null or not defined");
    }

    // 1. 将O赋值为调用map方法的数组.
    var O = Object(this);

    // 2.将len赋值为数组O的长度.
    var len = O.length >>> 0;

    // 3.如果callback不是函数,则抛出TypeError异常.
    if (Object.prototype.toString.call(callback) != "[object Function]") {
      throw new TypeError(callback + " is not a function");
    }

    // 4. 如果参数thisArg有值,则将T赋值为thisArg;否则T为undefined.
    if (thisArg) {
      T = thisArg;
    }

    // 5. 创建新数组A,长度为原数组O长度len
    A = new Array(len);

    // 6. 将k赋值为0
    k = 0;

    // 7. 当 k < len 时,执行循环.
    while(k < len) {

      var kValue, mappedValue;

      //遍历O,k为原数组索引
      if (k in O) {

        //kValue为索引k对应的值.
        kValue = O[ k ];

        // 执行callback,this指向T,参数有三个.分别是kValue:值,k:索引,O:原数组.
        mappedValue = callback.call(T, kValue, k, O);

        // 返回值添加到新数组A中.
        A[ k ] = mappedValue;
      }
      // k自增1
      k++;
    }

    // 8. 返回新数组A
    return A;
  };      
}
 

Array.prototype.some()


some() 方法测试数组中的某些元素是否通过由提供的函数实现的测试。

const isBiggerThan10 = (element, index, array) => {
return element > 10;
}

[2, 5, 8, 1, 4].some(isBiggerThan10);
// false

[12, 5, 8, 1, 4].some(isBiggerThan10);
// true

语法: arr.some(callback[, thisArg])

参数

callback
用来测试每个元素的函数。
thisArg
执行 callback 时使用的 this 值。

描述

some 为数组中的每一个元素执行一次 callback 函数,直到找到一个使得 callback 返回一个“真值”(即可转换为布尔值 true 的值)。如果找到了这样一个值,some 将会立即返回 true。否则,some 返回 falsecallback 只会在那些”有值“的索引上被调用,不会在那些被删除或从来未被赋值的索引上调用。

callback 被调用时传入三个参数:元素的值,元素的索引,被遍历的数组。

如果为 some 提供了一个 thisArg 参数,将会把它传给被调用的 callback,作为 this 值。否则,在非严格模式下将会是全局对象,严格模式下是 undefined

some 被调用时不会改变数组。

some 遍历的元素的范围在第一次调用 callback. 时就已经确定了。在调用 some 后被添加到数组中的值不会被 callback 访问到。如果数组中存在且还未被访问到的元素被 callback 改变了,则其传递给 callback 的值是 some 访问到它那一刻的值。

兼容

if (!Array.prototype.some)
{
Array.prototype.some = function(fun /*, thisArg */)
{
'use strict';

if (this === void 0 || this === null)
throw new TypeError();

var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== 'function')
throw new TypeError();

var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++)
{
if (i in t && fun.call(thisArg, t[i], i, t))
return true;
}

return false;
};
}

光标位置获取,设置,插入的操作

    var cursorPosition = {
        get: function (textarea) {
            var rangeData = {text: "", start: 0, end: 0};

            if (textarea.setSelectionRange) { // W3C 标准获取光标位置
                textarea.focus();
                rangeData.start = textarea.selectionStart;
                rangeData.end = textarea.selectionEnd;
                rangeData.text = (rangeData.start != rangeData.end) ? textarea.value.substring(rangeData.start, rangeData.end) : "";
            } else if (document.selection) { // IE
                textarea.focus();
                var i,
                    oS = document.selection.createRange(),
// Don't: oR = textarea.createTextRange()
                    oR = document.body.createTextRange();
                oR.moveToElementText(textarea);

                rangeData.text = oS.text;
                rangeData.bookmark = oS.getBookmark();

// object.moveStart(sUnit [, iCount])
// Return Value: Integer that returns the number of units moved.
                for (i = 0; oR.compareEndPoints('StartToStart', oS) &lt; 0 &amp;&amp; oS.moveStart("character", -1) !== 0; i++) {
// Why? You can alert(textarea.value.length)
                    if (textarea.value.charAt(i) == '\r') {
                        i++;
                    }
                }
                rangeData.start = i;
                rangeData.end = rangeData.text.length + rangeData.start;
            }

            return rangeData;
        },

        set: function (textarea, rangeData) { // 设置光标位置
            var oR, start, end;
            if (!rangeData) {
                alert("You must get cursor position first.")
            }
            textarea.focus();
            if (textarea.setSelectionRange) { // W3C
                textarea.setSelectionRange(rangeData.start, rangeData.end);
            } else if (textarea.createTextRange) { // IE
                oR = textarea.createTextRange();

// Fixbug : ues moveToBookmark()
// In IE, if cursor position at the end of textarea, the set function don't work
                if (textarea.value.length === rangeData.start) {
//alert('hello')
                    oR.collapse(false);
                    oR.select();
                } else {
                    oR.moveToBookmark(rangeData.bookmark);
                    oR.select();
                }
            }
        },

        add: function (textarea, rangeData, text) { // 向光标位置添加内容
            var oValue, nValue, oR, sR, nStart, nEnd, st;
            this.set(textarea, rangeData);

            if (textarea.setSelectionRange) { // W3C
                oValue = textarea.value;
                nValue = oValue.substring(0, rangeData.start) + text + oValue.substring(rangeData.end);
                nStart = nEnd = rangeData.start + text.length;
                st = textarea.scrollTop;
                textarea.value = nValue;
// Fixbug:
// After textarea.values = nValue, scrollTop value to 0
                if (textarea.scrollTop != st) {
                    textarea.scrollTop = st;
                }
                textarea.setSelectionRange(nStart, nEnd);
            } else if (textarea.createTextRange) { // IE
                sR = document.selection.createRange();
                sR.text = text;
                sR.setEndPoint('StartToEnd', sR);
                sR.select();
            }
        }
    }

let

let 方法  声明一个变量,这个变量的值可以改变, 与 var 不同的是他不会提升作用域, 而且变量声明之前赋值,会报错。 局部作用域,作用域外面拿不到。

const

const 方法 声明一个变量, 这个变量的值不可以改变, 但如果这个变量是对象,对象的值是可以改变的,为了安全考虑。 其他与 let 相同。

箭头函数 =>

=> 箭头函数 用法与 function 相同  区别:箭头函数 this 指向不会改变,也就是绑定了上下文 this 的指向;

  
示例:
  var fun = (val,opend)=>{ return val + opend };
  var Fun = function(val,opend){ return val + opend };

Symbol

ES5的对象属性名都是字符串,这容易造成属性名的冲突,例如你用的他人提供的方法,但又想为这个对象添加新的方法(mixin模式)新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是ES6引入Symbol的原因。
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,前六种是:Undefined、Null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。
Symbol值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的Symbol类型。凡是属性名属于Symbol类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。

let s = Symbol();
typeof s
// "symbol"

上面代码中,变量s就是一个独一无二的值。typeof运算符的结果,表明变量s是Symbol数据类型,而不是字符串之类的其他类型。
注意,Symbol函数前不能使用new命令,否则会报错。这是因为生成的Symbol是一个原始类型的值,不是对象。也就是说,由于Symbol值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型。
Symbol函数可以接受一个字符串作为参数,表示对Symbol实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。

不用不知道,一用就感觉自己的会的东西太少了:

数组属性 作用 返回值
arr.push(item1,item2…) 可以向数组最后添加一个或多个元素 返回数组的新长度,改变原数组。
arr.pop() 从数组最后删除一个元素 返回删除掉的元素值,改变原数组
arr.unshift(item1,item2…) 可以向数组前面添加一个或多个元素 返回数组的新长度,改变原数组
arr.shift() 从数组前面删除一个元素 返回删除掉的元素值,改变原数组
arry.join("字符串") 使用字符串连接数组的每一个元素 返回一个新的字符串,不改变原数组
arry.concat(一个或多个数组) 方法用于连接两个或多个数组 返回一个新数组,不改变原数组
arry.slice(start,end) 可以拷贝数组中从索引start开始,到end前一位的元素值,以数组形式返回。不改变原数组。 返回一个新数组,不改变原数组
arry.toString() 可以将数组转换为字符串形式(不常用) 返回字符串,不改变原数组
arry.indexOf(参数1,参数2) 参数1表示要找哪个元素,返回找到的索引值。第二个参数是一个索引值,表示从哪个位置开始查找。
没有找到,返回-1
查找到参数:返回索引值,没有就返回 -1(IE9 以上可用)
arry.reverse() 该方法用于颠倒元素的顺序 改变原来的数组,不会创建新的数组