【holm】JavaScript复习&再学习:超基础

javascript是一门动态脚本语言。通过原型链实现面向对象。

基础

数据结构

  • Numeber

  • bool

  • string

    • 模板字符串
    • indexOf
    • substring
    • slice(更灵活,可以使用负数作为参数)
  • Array

    • 包含任意数据类型
    • 可以随时给length赋值(不推荐)
    • slice
    • pushpop
    • unshift(头部添加若干元素)和shift(删掉第一个元素)
    • sort
    • reverse
    • splice
    • concat
    • join
      常用迭代方法:
    • map(映射)
    • reduce
    • filter:filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。
    • sort(会直接对Array进行修改)
    • every:判断数组的所有元素是否满足测试条件。
    • find:查找符合条件的第一个元素。
    • findIndex:查找符合条件的第一个元素的索引。
    • forEach

使用mapreduce将字符串转化成Number:

function string2int(s) {
  var arr= Array.from(s).map(
      x=>{
      switch(x){
          case '0': return 0;break;
          case '1': return 1;break;
          case '2': return 2;break;
          case '3': return 3;break;
          case '4': return 4;break;
          case '5': return 5;break;
          case '6': return 6;break;
          case '7': return 7;break;
          case '8': return 8;break;
          case '9': return 9;break;
          default: return null;
          }
        }
    );
return arr.reduce((x,y) => x*10 + y);
}
  • object : 由键值对组成的无序集合
var obj={
    option1:{
        x1:'996',
        x2:'work'
    },
    option2:{
        x1:'965',
        x2:'life'
    }
}
obj.option3;//undefined
obj.option3={
    x1:'',
} //新增属性
obj.option3.x2='';//新增属性

delete obj.option1.x2;//删除option1属性(对象)中的x2属性
delete obj.option1;//删除option1属性

obj.option1;//undefined
delete obj['option3'];//另一种删除键值对的方式

'option2' in obj;//true
'option3' in obj;//false

'toString' in obj;//true 通过继承得到。 obj在原型链上指向`object`,所以拥有`toString`属性

obj.hasOwnProperty('option2');//true
obj.hasOwnProperty('toString');//false

在对象中绑定的函数称为这个对象的方法。

  • map: ES6

JavaScript的默认对象表示方式{}可以视为其他语言中的MapDictionary的数据结构,即一组键值对。但是JavaScript的对象有个小问题,就是键必须是字符串。但实际上Number或者其他数据类型作为键也是非常合理的。
为了解决这个问题,最新的ES6规范引入了新的数据类型Map

  • set: ES6
    • set是一组key的集合(不能重复)
    • 新建set时可以直接传入Array作为输入
      Set用于数组去重:
var arr=[1,2,2,3,5,6];
console.log("初始数组:"+arr);//1,2,2,3,4,5

var s=new Set(arr);
console.log(s);//1,2,3,5,6

var arr2=Array.from(s);
console.log("去重后的数组:"+arr2);//1,2,3,5,6
  • iterable: ES6
    Array、Map和Set都属于iterable类型。
    具有iterable类型的集合可以通过新的for ... of循环来遍历。

语句

  • var

  • let:块级作用域的变量。

  • const:块级作用域的常量。

  • 解构赋值 var {x, y, z} = {'hello', 'JavaScript', 'ES6'};(如果x,y,z提前声明则要要将整条语句用小括号包裹,以免被当成块处理)

    • 使用的变量名可以和属性名不一致 {x,y,oldZ:Z}
    • 可以使用默认值{x,y,z=1}
    • 使用场景:
      • 交换xy的值:{x,y}={y,s}
      • 快速获取当前页面的域名和路径:var {hostname:domain, pathname:path} = location;
  • for ... in 注意Array是一种对象,而它的每个元素的索引被视为对象的属性,因此,for ... in循环得到的是Array的索引

  • for ... of

  • 最好使用forEach方法

  • ==(相等运算符)和===(严格运算符)

  1. 对于string,number等基础类型,=====是有区别的
    • 不同类型间比较,==之比较“转化成同一类型后的值”(自动调用toStringvalueOf)看“值”是否相等,===如果类型不同,其结果就是不等
    • 同类型比较,直接进行“值”比较,两者结果一样(进行=比较,返回=的比较值)
    • ==不具有传递性
    • 如果两个值不具有相同类型,也有可能返回true
    • 如果一个值是null另一个值是undefined,返回true
    • 如果一个值是string另一个是number,会把string转换成number再进行比较
    • 如果一个值是true,会把它转成1再比较,false会转成0
    • 如果一个值是Object,另一个是number或者string,会把Object利用valueOf()或者toString()转换成原始类型再进行比较
    • Undefined是基本类型,它转换成数字是NaNNaN和谁对比结果都是false,包括自己
    • Null是复合对象,它没有ValueOf()toString(),它只有与undefind和自己对比时结果是true
  2. 对于Array,Object等高级类型,=====是没有区别的,进行的是“指针地址”比较
    • 要是两个值类型不同,返回false
    • 要是两个值都是number类型,并且数值相同,返回true
    • 要是两个值都是stirng,并且两个值的String内容相同,返回true
    • 要是两个值都是true或者都是false,返回true
    • 要是两个值都是指向相同的ObjectArray或者function,返回true
    • 要是两个值都是null或者都是undefined,返回true
  3. 对于明确数据类型的用===更为可靠,JavaScript是一门弱类型语言,表达式运算赋值等操作都会导致类型转换。

函数

  • function func(x){}

  • var func=function(x){};

  • arguments:永远指向当前函数的调用者传入的所有参数。(类似Array但不是Array

  • 使用rest接受多余参数:function func(x1,x2,...rest){}rest存放一个数组)

  • 利用call()apply()bind改变this的指向
    区别在于:

    1. Function.prototype.call(thisArg[, arg1, arg2, ...argN])分别接受参数。
    2. Function.prototype.apply(thisArg [, argsArray])接受数组形式的参数。
    3. call()apply()都是立即调用。
    4. bind()方法会创建一个新函数(将之作为返回值返回),称为绑定函数。当调用这个绑定函数时,绑定函数会以创建它时传入bind()方法的第一个参数作为this,传入bind()方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。
  • 变量提升:JavaScript引擎会自动提升变量的声明,但不会提升变量的赋值;

  • 全局变量会绑定到window上,不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,都会造成命名冲突,将自己的代码全部放入唯一的名字空间中以减少全局变量冲突的可能。

  • this代表函数运行时,自动生成的一个内部对象,只能在函数内部使用,在函数执行时被绑定;

    • **如果没有用obj.xxx()的形式调用函数,this会指向全局对象window。(巨大的设计错误)
    • var that = this; 所以有了这句话:调用方法前首先捕获this
  • JavaScript引擎有一个在行末自动添加分号的机制,小心return

this这个 keyword非常的困惑,但是其实有一个好方法可以理解.

  1. 检查 ' . ' 左边是谁invoke 这个函数. 例如 xiaoming.age(); age函数里面有this, 然后 '. ' 旁边是xiaoming , 那么this就是指向xiaoming了.这种叫做 Implicit Binding.

  2. 如果点旁边没有,那就检查有没有用到 bind, apply, call 这三种, 有的话就是调用此方法的对象. 这种叫做 explicit binding.

  3. 如果上面两个都没有就检查代码里面有没有用到new 这个keyword, 有的话那就是指向new旁边的函数对象. 这种叫做new binding

  4. 上面三个都没有, 检查是不是有arrow function, 有arrow function的话就是, 那么指向是arrow function的lexical binding 的对象. 就是她的parent. 这种叫做 lexical binding

  5. 全部都没有如果不是strict mode那就是window对象了.. strict就是 error (undefined).

参考资料

原文地址:https://www.cnblogs.com/holm/p/12832139.html