es6基础

在 ECMAScript 中,变量可以存在两种类型的值,即原始值和引用值。
原始值:存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。
引用值:存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处。
一、原始类型
ECMAScript 有 5 种原始类型(primitive type),即 Undefined、Null、Boolean、Number 和 String。
1、 typeof 运算符
对变量或值调用 typeof 运算符将返回下列值之一:
undefined - 如果变量是 Undefined 类型的
boolean - 如果变量是 Boolean 类型的
number - 如果变量是 Number 类型的
string - 如果变量是 String 类型的
object - 如果变量是一种引用类型或 Null 类型的

var oTemp;
alert(oTemp == undefined); //输出 "true"
alert(typeof oTemp); //输出 "undefined"

以下代码第一句输出的是 “undefined”,即使变量 oTemp2 从未被声明过。如果对 oTemp2 使用除 typeof 之外的其他运算符的话,会引起错误,因为其他运算符只能用于已声明的变量上。

alert(typeof oTemp2);  //输出 "undefined"
alert(oTemp2 == undefined); //报错

当函数无明确返回值时, typeof 运算符返回的也是值 "undefined"

function testFunc() {
}

alert(testFunc() == undefined);  //输出 "true"    !!!

值 undefined 实际上是从值 null 派生来的,因此 ECMAScript 把它们定义为相等的,但它们的含义不同。undefined 声明了变量但未对其初始化 时赋予该变量的值null 表示尚未存在的对象(在讨论 typeof 运算符时,简单地介绍过这一点)。如果函数或方法要返回的是对象,那么找不到该对象时,返回的通常是 null。

alert(null == undefined);  //输出 "true"

2、特殊的number值
浮点数进行计算前,真正存储的是字符串。
MAX_VALUE 可表示的最大的数。
MIN_VALUE 可表示的最小的数。
NaN 非数字值。
NEGATIVE_INFINITY 负无穷大,溢出时返回该值。
POSITIVE_INFINITY 正无穷大,溢出时返回该值。

isFinite() 方法,检查其参数是否是无穷大。
如果 number 是有限数字(或可转换为有限数字),那么返回 true。否则,如果 number 是 NaN(非数字),或者是正、负无穷大的数,则返回 false。

document.write(isFinite(123)+ "<br />")                          //true
document.write(isFinite(-1.23)+ "<br />")                        //true
document.write(isFinite(5-2)+ "<br />")                          //true
document.write(isFinite(0)+ "<br />")                             //true
document.write(isFinite("Hello")+ "<br />")                    //false
document.write(isFinite("2005/12/12")+ "<br />")          //false

NaN表示非数,一般发生在类型转换失败时。例如,要把单词 blue 转换成数值就会失败,因为没有与之等价的数值。不能用于算术计算与自身不相等

alert(NaN == NaN);  //输出 "false"

alert(isNaN("blue"));  //输出 "true"
alert(isNaN("666"));  //输出 "false"

二、类型转换
1、转数字
** parseInt() parseFloat() 转换第一个无效字符之前的字符串**
parseInt()

var iNum1 = parseInt("12345red");    //返回 12345
var iNum1 = parseInt("0xA");    //返回 10
var iNum1 = parseInt("56.9");    //返回 56
var iNum1 = parseInt("red");    //返回 NaN
var iNum1 = parseInt("AF", 16);    //十六进制,返回 175

parseFloat() 字符串必须以十进制形式表示浮点数

var fNum1 = parseFloat("12345red");    //返回 12345
var fNum2 = parseFloat("0xA");    //返回 NaN
var fNum4 = parseFloat("11.22.33");    //返回 11.22
var fNum5 = parseFloat("0102");    //返回 102

2、强制转换
1)Boolean(value) - 把给定的值转换成 Boolean 型;
当要转换的值是至少有一个字符的字符串、非 0 数字或对象时,Boolean() 函数将返回 true。如果该值是空字符串、数字 0、undefined 或 null,它将返回 false。

var b1 = Boolean("");        //false - 空字符串
var b2 = Boolean("hello");        //true - 非空字符串
var b1 = Boolean(50);        //true - 非零数字
var b1 = Boolean(null);        //false - null
var b1 = Boolean(0);        //false - 零
var b1 = Boolean(new object());    //true - 对象

2)Number(value) - 把给定的值转换成数字(可以是整数或浮点数);
用 Number() 进行强制类型转换,“1.2.3” 将返回 NaN,因为整个字符串值不能转换成数字。如果字符串值能被完整地转换,Number() 将判断是调用 parseInt() 方法还是 parseFloat() 方法。

3)String(value) - 把给定的值转换成字符串;

三、引用类型
对象是由 new 运算符加上要实例化的对象的名字创建的。

var o = new Object();

1、Object 对象
属性:
constructor:对创建对象的函数的引用(指针)。对于 Object 对象,该指针指向原始的 Object() 函数。
prototype:对该对象的对象原型的引用。对于所有的对象,它默认返回 Object 对象的一个实例。

方法:
hasOwnProperty(property):判断对象是否有某个特定的属性。(例如,o.hasOwnProperty(“name”))
IsPrototypeOf(object):判断该对象是否为另一个对象的原型。
PropertyIsEnumerable:判断给定的属性是否可以用 for…in 语句进行枚举。

注:上面列出的每种属性和方法都会被其他对象覆盖。
2、Number 对象
要得到数字对象的 Number 原始值,使用 valueOf()

var iNumber = oNumberObject.valueOf();

toFixed() 返回指定位数小数的数字的字符串表示

var oNumberObject = new Number(68);
alert(oNumberObject.toFixed(2));  //输出 "68.00"

注:toFixed() 方法能表示具有 0 到 20 位小数的数字,超过这个范围的值会引发错误。

toExponential():返回用科学计数法表示的数字的字符串形式,参数指定要输出的小数的位数:

var oNumberObject = new Number(68);
alert(oNumberObject.toExponential(1));  //输出 "6.8e+1"

toPrecision() :返回指定数字总数的预定形式或指数形式。参数用于表示数的数字总数(不包括指数)。会对数进行舍入

var oNumberObject = new Number(68);
alert(oNumberObject.toPrecision(1));  //输出 "7e+1",即70

alert(oNumberObject.toPrecision(3));  //输出 "68.0"

3、String 对象
charAt() :返回指定位置处的字符串

var oStringObject = new String("hello world");
alert(oStringObject.charAt(1));    //输出 "e"

concat() :连接一个/多个字符串,返回String 原始值,原始的 String 对象不变相当于+号

var oStringObject = new String("hello ");
var sResult = oStringObject.concat("world");
alert(sResult);        //输出 "hello world"
alert(oStringObject);    //输出 "hello "

instanceof 识别正在处理的对象的类型。与 typeof 方法不同的是,instanceof 方法要求开发者明确地确认对象为某特定类型。

var oStringObject = new String("hello world");
alert(oStringObject instanceof String);    //输出 "true"

四、运算符
1、delete 运算符 删除对以前定义的对象属性或方法的引用,不能删除开发者未定义的属性和方法

var o = new Object;
o.name = "David";
alert(o.name);    //输出 "David"
delete o.name;
alert(o.name);    //输出 "undefined"

2、void 运算符 对任何值返回 undefined。通常用于避免输出不应该输出的值,没有返回值的函数真正返回的都是 undefined。

<a href="javascript:void(window.open('about:blank'))">Click me</a>

不加void 运算符,点击其中的链接,即可看到屏幕上显示 “[object]”。因为 window.open() 方法返回了新打开的窗口的引用,然后该对象将被转换成要显示的字符串。

五、语句
1、arguments对象
在函数代码中,使用特殊对象 arguments,开发者无需明确指出参数名,就能访问它们

function sayHi() {
  alert(arguments[0]);
}

还可以用 arguments 对象检测函数的参数个数,引用属性 arguments.length 即可

function howManyArgs() {
  alert(arguments.length);
}

howManyArgs("string", 45);    //2
howManyArgs();                    //0
howManyArgs(12);               //1

注:ECMAScript 不会验证传递给函数的参数个数是否等于函数定义的参数个数。开发者定义的函数都可以接受任意个数的参数(根据 Netscape 的文档,最多可接受 25 个),而不会引发任何错误。任何遗漏的参数都会以 undefined 传递给函数,多余的函数将忽略。
2、Function 对象
用 Function 类直接创建函数的语法如下:

var function_name = new function(_arg1_, _arg2_, ..., _argN_, _function_body_)

每个 arg 都是一个参数,最后一个参数是函数主体。这些参数必须是字符串。

var sayHi = new Function("sName", "sMessage", "alert(\"Hello \" + sName + sMessage);");

如果函数名只是指向函数的变量,那么可以把函数作为参数传递给另一个函数

function callAnotherFunc(fnFunction, vArgument) {
  fnFunction(vArgument);
}

var doAdd = new Function("iNum", "alert(iNum + 10)");

callAnotherFunc(doAdd, 10);    //输出 "20"

ECMAScript 定义的Function 对象的属性 length 声明了函数期望的参数个数

function doAdd(iNum) {
  alert(iNum + 10);
}
alert(doAdd.length);    //输出 "1"

Function 对象也有与所有对象共享的 valueOf() 方法和 toString() 方法。这两个方法返回函数源代码,在调试时尤其有用。

function doAdd(iNum) {
  alert(iNum + 10);
}
document.write(doAdd.toString());

3、闭包
闭包,指的是词法表示包括不被计算的变量的函数,也就是说,函数可以使用函数之外定义的变量
在 ECMAScript 中使用全局变量是一个简单的闭包实例。

var sMessage = "hello world";

function sayHelloWorld() {
  alert(sMessage);
}

sayHelloWorld();

在上面这段代码中,脚本被载入内存后,并没有为函数 sayHelloWorld() 计算变量 sMessage 的值。该函数捕获 sMessage 的值只是为了以后的使用,也就是说,解释程序知道在调用该函数时要检查 sMessage 的值。sMessage 将在函数调用 sayHelloWorld() 时被赋值,显示消息 “hello world”。

在一个函数中定义另一个会使闭包变得更加复杂。

var iBaseNum = 10;

function addNum(iNum1, iNum2) {
  function doAdd() {
    return iNum1 + iNum2 + iBaseNum;
  }
  return doAdd();
}

这里,函数 addNum() 包括函数 doAdd() (闭包)。内部函数是一个闭包,因为它将获取外部函数的参数 iNum1 和 iNum2 以及全局变量 iBaseNum 的值。 addNum() 的最后一步调用了 doAdd(),把两个参数和全局变量相加,并返回它们的和。
这里要掌握的重要概念是,内部函数doAdd() 函数根本不接受参数,它使用的值是从执行环境中获取的

六、对象
1、面向对象
一种面向对象语言需要向开发者提供四种基本能力:
封装 - 把相关的信息(无论数据或方法)存储在对象中的能力
聚集 - 把一个对象存储在另一个对象内的能力
继承 - 由另一个类(或多个类)得来类的属性和方法的能力
多态 - 编写能以多种方法运行的函数或方法的能力

2、对象作用域
ECMAScript 只有公用作用域,所有对象的所有属性和方法都是公用的。

由于缺少私有作用域,开发者确定了一个规约,在属性前后加下划线把变量看为私有的。下划线并不改变属性是公用属性的事实,它只是告诉其他开发者,应该把该属性看作私有的。

obj._color_ = "blue";

严格来说,ECMAScript 并没有静态作用域。不过,它可以给构造函数提供属性和方法。

function sayHello() {
  alert("hello");
}

sayHello.alternate = function() {
  alert("hi");
}

sayHello.alternate();    //输出 "hi"

这里,方法 alternate() 实际上是函数 sayHello 的方法。可以调用 sayHello.alternate() 输出 “hi”。即使如此,alternate() 也是 sayHello() 公用作用域中的方法,而不是静态方法。

3、this
关键字this用在对象的方法中,指向调用该方法的对象

var oCar = new Object;
oCar.color = "red";
oCar.showColor = function() {
  alert(`this.color`);
};

oCar.showColor();        //输出 "red"

在上面的代码中,关键字 this 用在对象的 showColor() 方法中。在此环境中,this 等于 oCar。

为什么使用 this 呢?因为在实例化对象时,总是不能确定开发者会使用什么样的变量名。使用 this,即可在任何多个地方重用同一个函数。

4、修改对象
prototype 属性不仅可以定义构造函数的属性和方法,还可以为本地对象添加属性和方法。
1)通过已有的方法创建新方法

Number.prototype.toHexString = function() {
  return this.toString(16);
};

var iNum = 15;
alert(iNum.toHexString());        //输出 "F"

2)重命名已有方法

Array.prototype.enqueue = function(vItem) {
  this.push(vItem);
};

Array.prototype.dequeue = function() {
  return this.shift();
};

3)添加与已有方法无关的方法

//在数组中检索每个项,直到发现与传进来的项相同的项目为止。如果找到相同的项,则返回该项的位置,否则,返回 -1。
Array.prototype.indexOf = function (vItem) {
  for (var i=0; i<this.length; i++) {
    if (vItem == this[i]) {
      return i;
    }
  }
  return -1;
}

var aColors = new Array("red","green","blue");
alert(aColors.indexOf("green"));    //输出 "1"

4)为本地对象添加新方法
如果想给 ECMAScript 中每个本地对象添加新方法,必须在 Object 对象的 prototype 属性上定义它。所有本地对象都继承了 Object 对象,所以对 Object 对象做任何改变,都会反应在所有本地对象上。

Object.prototype.showValue = function () {
  alert(this.valueOf());
};

var str = "hello";
var iNum = 25;
str.showValue();        //输出 "hello"
iNum.showValue();        //输出 "25"

5)重定义已有方法

Function.prototype.toString = function() {
  return "Function code hidden";
}

function sayHi() {
  alert("hi");
}
alert(sayHi.toString());    //输出 "Function code hidden"

不过,toString() 指向的原始函数将被无用存储单元回收程序回收,因为它被完全废弃了。没有能够恢复原始函数的方法,所以在覆盖原始方法前,比较安全的做法是存储它的指针,以便以后的使用。

`Function.prototype.originalToString = Function.prototype.toString;`

Function.prototype.toString = function() {
  if (this.originalToString().length > 100) {
    return "Function too long to display.";
  } else {
    return this.originalToString();
  }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值