002JS之ECMAScript和function

1.ECMAScript

1.1 JS组成

ECMAScript:js核心语法、数据类型…;
DOM文档对象模型:访问和操作HTML文档的方法规定;
BOM浏览器对象模型:浏览器描述当前窗口的属性和状态的内存全局对象

1.2 数据类型

为什么要换分数据类型?:不同类型的数据会有不同的特征和不同的操作方法。
数据类型分类

  • 按照ECMASCript划分,分为简单类型和复合类型两种。
    简单类型:Number、String、Boolean、null、undefined、symbol(ES6);
    复合类型:Object(Array、function、element、elements、类json的{}…)
  • 按照typeof检测划分,number、String、Boolean、function、undefined、symbol、object

1.3 typeof

typeof data:用于检测数据的类型,需要注意的是检测结果与ECMAScript规定的数据类型并不完全一致,例如null值在ECMAScript中被规定为基本数据类型,在typeof检测中被检测为object。

1.4 数据类型转换

数据类型的转换通常为转成数字、转为布尔、转为字符串。

1.4.1 转为数字

  • 转为整数:parseInt(data[,radix]);
    第一个参数是需要转成数字的数据,第二个参数是声明要转的数据进制基数;需要注意的是,0x为十六进制标识,没有指定基数时,直接转换以0x开头的数据时,是按照十六进制进行转换;
    转换规则为不是字符串的数据先转为字符串数据,然后从左至右进行逐位转换,遇到非基数进制的数字会停止转换,若第一位就是非基数进制的数字,结果为NaN;
    此函数的第一个功能将非数字转换为数字,第二个功能是将非整数数字转换为整数。
  • 转为浮点数:parseFloat(data);
    与parseInt函数不同的是,此函数只会转换十进制的数据,并且多转换一个小数点。
    需要注意的是js中,小数的计算会出现精度问题,原因是js底层进行计算时是先转为二进制,然后再进行计算的。
  • 转为数字:number(val);
    字符串类型,整个字符串均符合数字规则时,才能转成数字,否则为NaN;空字符串为0;
    布尔类型,true为1,否则为0;
    null为0;undefined为NaN;
    对象类型会先调用对象的toString方法转成字符串,再进行转换;空数组返回0;

1.4.2 转为布尔

boolean(val);数字非零为真,字符串非空串为真;null为假;NaN为假;对象为真;

1.4.3 转为字符串

string(val);数字返回数字字符串;undefined返回undefined字符串;null返回null字符串;布尔值返回相应的字符串;函数直接返回真个函数体组成的字符串;对象直接调用对象的toString方法进行转换。

1.4.4 隐式数据类型转换

有时候,数据类型的转换并不总是需要程序员进行直接编写代码进行的,有时js解析器在解析代码时,会自动将数据类型进行转换。例如非绝对比较时,整数和小数进行计算时等。

1.4.5 数据类型强制转换规则表

数据类型强制转换表

1.5 NaN

NaN是number数据类型的一个特殊值,但不是数字,它所具有的特性是自己也不等于自己,谁也不等于它。
isNaN(val);此函数判断是否为NaN,如果能合法转成数字就为false,否则就是true,即是NaN。

1.6 传值和传址

基本类型(简单类型)也被称作是传值类型,在这一类数据类型进行赋值、传参等操作时,传递的是真实的具体的值;
对象类型(复合类型)也被称作是传址类型,这一类型的数据在赋值、传参等操作时,传递并不是真实的具体的值,而是数据在内存中的引用地址。

2. function

2.1 函数基础

2.1.1 函数声明与调用

// 函数声明
function funcName(形参列表){/* 函数体即逻辑代码*/}
var name = function(形参列表){/* 函数体即逻辑代码*/} // 函数表达式

// 函数非事件调用
funcName(实参列表);
name(实参列表);

// 函数声明和自调用
(function(形参列表){/* 函数体即逻辑代码*/})(实参列表);

// 函数的事件调用
el.event = fn;

2.1.2函数传参

应用场景:当有多端代码相似时,只有个别地方不同,此时可以通过传入的参数作为区别代码的依据。

  • 形参和实参
    形式参数是在声明函数时的概念,JS中的形参与其他编程语言的形式声明参数略有不同之处。直接在函数声明的小括号内写上形参名字即可,不用在参数前添加数据类型。但在后面的JS标准中也加入了类似的数据类型规范,只是形式上略有不同。
    实参是调用函数时进行的,调用者只需要将需要的数据放在执行函数的小括号内即可。
    注意:JS中存在不定参和默认参数的情况,后面的JS中还会有涉及。
  • arguments不定参
    在函数内部可以直接使用arguments这个名字,它的本质上是一个数组,数组内部存储的是我们传入的参数。因为JS采用了函数的参数个数是不一定的,也就是说实参个数与形参个数并不是必须要一致的,此时arguments这个数组包含了调用者所有实际传入的所有参数。
    arguments这个数组和其他数组一致,使用[num]访问内部元素和使用length获取元素的个数。

2.1.3 return返回值

定义:返回函数执行的结果;
return作用:设置函数执行后的结果,终结函数执行;
注意事项:必须在函数内使用,函数外使用会被报错,该语句执行后,函数会结束执行,即后面即使有代码也不会再执行。每个函数都会有返回值,当没有定义时,默认返回undefined。

2.1.4 其他

  • 事件是元素本身就具有的属性,通常说为元素添加事件,其实质是为元素已有的相应元素添加事件处理函数。
  • console.dir();用于打印对象的所有属性和方法。
  • 获取元素计算后样式
    getComputedStyle(el);获取优先级最高的样式,即元素当前显示出来的所有样式;
    getComputedStyle(el)['attr'];获取指定元素属性数据;
    需要注意的是IE8一下不支持这一方法,需要使用el.currentStyle['attr'];获取当前元素的属性数据。

2.2 js预解析机制

JS预解析机制也称为变量提升,通常被认为是JavaScript执行上下文(特别是在创建和执行阶段)工作方式的一种认识。其中包括var提升和function提升。
从字面意义上解读,“变量提升”意味着变量和函数会在物理层面移动到代码的最前面,但是,简单的这样理解是不够全面的,因为它没有不仅仅如此。实际上,变量的和函数的声明在代码中的位置是不会移动的,而是在代码编译阶段被放到内存中时被提前了,其实,还不是仅仅这么简单,因为JS的世界里从来就没有代码编译这个概念,这源于JS这门语言是一门标记语言,它的代码不是被编译而是被JS底层代码解析器进行了解析,这一过程虽然与传统编程语言很详细,但却还是有很大不同的。下面我会简单的阐述一下它们的异同,仅作为了解,一遍我们简单地理解成编译就可以了。
传统编译语言要想执行一段代码,即使是hello world,也是需要经过分词/词法分析、解析/语法分析、代码生成这三个编译阶段的;但是对于JS来说,大部分的编译时发生在代码执行前的几微秒,这个事件是相当的短暂的,1毫秒只有1秒的一百万分之一,简单的来说就是,任何JS代码在执行前就已经在极短的时间里进行了编译。参与编译的成员主要有:从头干到尾的JavaScript引擎,主要负责程序的编译和执行过程;还有负责语法分析和代码生成等脏活的编译器;当然还有负责收集并维护有所有声明的标识符组成的一系列查询且根据一套非常严格规则确定当前执行的代码对这些标识符的访问权限的作用域。
上面扯了这么多,竟然还没有说到预解析机制的表现层。

  • 预解析的对象是变量和函数,当代码进行编译时,底层会将所有的var和function声明的代码提升到当前声明代码的作用域的最前面。
    需要注意的是var变量声明的提升仅仅局限于声明,不包含赋值;function会将其整个函数体进行提升;另外需要注意的是预解析时会首先预解析当前作用域下的var,后解析function,因此若产生同名,后者会覆盖前者。

2.3 作用域和作用链

作用域通常来说就是一段代码中使用的的变量和函数并不是任何时候都是可用的,这源于JS对变量和函数进行了可用性范围进行了限定,即作用域。增加作用域限定提高了程序逻辑的局部性,增强了程序的可靠性,同时也减少了命名冲突的问题。
分类:作用域分为全局作用域和局部作用域,其中局部作用域又分为函数作用域和ES6规定的块作用域。
全局作用域是指在任何函数外通过var或function声明的代码,这些数据可以在全局任何地方都可以被调用。需要指出的是,JS中有一个window对象,它是js在浏览器中的顶层对象,其方法和属性都是全局的,window下的属性和方法可以直接调用,不用添加window作限定。var和function声明的数据会自动被挂载到window对象上,另外在非严格模式下未经声明就使用的变量也属于全局变量,也会被挂载到window上,需要指出的是这是JS的一个bug,若使用了严格模式再这样使用会报错。
函数作用域是只在函数内部通过var或function进行声明的数据,这些数据只能在当前函数内部被使用。
注意:不推荐过多的使用全局变量,这会造成全局污染,简单的来说就是在全局中产生了命名冲突导致了代码冲突,从而会给代码带来不可预测的风险和不确定性。
**作用域链:**作用域链也就是JS中数据的查找规则,在js中调用一段数据的时候,会首先在数据调用的当前作用中查找,其次在其父作用域查找,若依旧没有找到,会继续向上一层父作用域进行查找,直至找到全局作用域,依旧没有找到就会报错。作用域链
闭包其实质就是运用了作用域链的表现层,子作用域调用父作用域的数据,导致父作用域的数据保持了被引用,无法通过JS的垃圾回收机制进行回收,这种方式保持数据依旧具有数据的暂时持久化。函数对象可以通过作用域链相互关联起来,函数体内声明的数据都可以保存在函数的作用域内,这种特性在计算机科学中被称为闭包。即函数体内的数据隐藏域作用域链内,看起来像是函数将数据包裹了起来,从动技术角度来说,js的所有函数属于闭包,因为函数都是对象,都关联到作用域链,函数内的数据都被保存在函数作用域内。

// 常见的闭包形式
function (){
	var a=0;
	return function(){console.log(a++);}
}

function(){
	var a=0;
	for(var i=0;i<3;i++){
		(function(){a++;})();
	}
}

function(){
	var a=0;
	el.onclick = (function(){return function(){a++};})();
}

var func = function(){
	var a = 0;
	return function(){a++};
}

2.4 this指向

this是指当前代码的环境对象。任何函数外this指向window;函数内谁调用这个函数this就指向谁。
需要注意的是使用严格模式(use strict)下function的this体现了JS更合理、更安全、更严谨的发展方向,严格模式下function如果不是作为对象属性调用,this指向undefined。
默认情况下,作为对象的属性(方法、事件等)调用,指向当前对象,其余情况指向window。
具体的指向如下:

  • 全局调用 函数名()指向window;
  • 对象调用 对象.函数名() 谁调用指向谁;
  • 自执行函数指向window;
  • 事件处理函数指向事件源;
  • 定时器处理函数指向事件源;
  • 函数定义了未调用的时候指向不确定。

JS中默认的this指向并不是一成不变的,是可以通过函数进行修改的。
修改指向:call()、apply()、bind()。

 // call();
 fn.call(新指向对象,从第二个参数开始是函数本身需要的参数);
// apply();
fn.apply(新指向对象,[]数组内填写函数本身需要的参数);
// 说明:call()和apply()实质上是一样的,都是在执行函数的的同时改变this指向,只是传递函数本身需要的函数的方式不同,前者是逐个用逗号隔开,后者是写在了数组内。

// bind()
fn.bind(新指向对象,函数本身需要的参数);
/*在形式上bind()与call()一致,
但还是有区别的,bind()方式改变的this指向在执行的过程后不仅会改变this指向,并且会返回一个新的函数,并把原函数的函数体赋值到要返回的新函数内,
还有bind更改this指向所返回的新函数不能再次更改this执行;
需要注意的是这种方式并不会执行原函数;
bind()修改指向时,传入的函数本身所需的参数会和返回后的新函数调用时传入的实参进行合并,通过arguments可以获取; 
*/

底层实现bind完成分析为什么bind更改this指向返回的新函数不能再次被更改this指向

function bind (fn,_this,...arg){
	return function(...arg2){
		fn.call(_this,...arg,..arg2);
	};
}

3.next

下一小结分享JS的定时器、日期对象、数组和字符串方法的知识点。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值