资讯专栏INFORMATION COLUMN

高程(第五章) 引用类型

fxp / 480人阅读

摘要:对数组中的每一项运行给定函数,返回该函数会返回的项组成的数组。这些类型与其他引用类型相似,但同时也具有与各自的基本类型相应的特殊行为。此外,所有原生引用类型的构造函数,像和,也都是对象的属性。

1 Object类型

创建对象实例:

new操作符后跟Object构造函数

ver person = new Object();
person.name = "Nicolas";
person.age = 29;

对象字面量表示法

var person = {
    name : "Nicholas",
    age : 29
}

通过对象字面量定义对象时,实际上不会调用Object构造函数

2 Array类型

创建数组:

使用Array构造函数

var colors = new Array(20);    //new可以省略,20表示数组长度

数组字面量表示法

var colors = ["red", "blue", "green"];
2.1 检测数组

使用instanceof操作符

console.log(value instanceof Array);    //只有一个全局作用域时使用

如果网页中包含多个框架,那实际上就存在两个以上不同的全局执行环境,从而存在两个以上不同版本的Array构造函数

使用Array.isArray()方法

console.log(Array.isArray(value));    //确定value是否数值,不管它是在哪个全局执行环境中创建的
2.2 转换方法

toLocaleString()

toString()

valueOf()

join()

var colors = ["red", "green", "blue"];
console.log(colors.join("||"));        //red||green||blue
2.3 栈方法

push():在数组末尾添加项,返回数组长度

pop():移除数组最后一项,返回移除的项

2.3 队列方法

shift():移除数组第一项,返回移除的项

unshift():在数组前端添加项,返回数组长度

2.5 重排序方法

reverse():反转数组的顺序

sort():按照升序排列数组项

sort()方法会调用每个数组项的toString()转型方法,然后比较得到的字符串
可接收一个比较函数作为参数,比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等则返回0,如果第一个参数应该位于第二个之后则返回一个正数;如下:

function compare(value1, value2){
    return value2 - value1;    //降序排序
}
2.6 操作方法

concat():用于拼接数组

slice():用于获取数组中的某几个项

splice():主要用途是向数组的中部插入项

2.7 位置方法

indexOf():从数组的开头查找某一项

lastIndexOf():从数组的末尾查找某一项

两个方法都返回要查找的项在数组中的索引,没找到的情况下返回-1

2.8 迭代方法

every():对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true。

filter():对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组。

forEach():对数组中的每一项运行给定函数,这个方法没有返回值。

map():对数组中的每一项运行给定函数,返回每次函数条用的结果组成的数组

some():对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true。

以上方法都不会修改数组中的包含的值

2.9 归并方法

以下两个方法都会迭代数组的所有项,然后构建一个最终返回的值。这两个方法都接收两个参数:一个在每一项上调用的函数和(可选的)作为归并基础的初始值。传入的函数接收4个参数:前一个值、当前值、项的索引和数组对象。这个函数的返回值会作为参数自动传给下一项。

reduce():从数组第一项开始,逐个遍历到最后

reduceRight():从数组的最后一项开始,向前遍历到第一项

var values = [1,2,3,4,5];
var sum = values.reduce(function(prev, cur, index, array){
    return prev + cur;
});
alert(sum);     //15

reduceRight()除了遍历方向的不同之外,与reduce()方法完全一致。

5 Function 类型

函数是对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。

function sum(num1, num2){        //会先进行函数声明提升
    return num1 + num2;
}

var sum = function(num1, num2){        //不会进行函数声明提升
    return num1 + num2;
}

var sum = new Function("num1", "num2", "return num1 + num2");    //不推荐,会导致解析两次代码
5.3 作为值的函数

因为ECMAScript中的函数名本身就是变量,所以函数也可以作为值来使用。也就是说,不仅可以像传递参数一样把一个函数传递给另一个函数,也可以将一个函数作为另一个函数的结果返回。

function createComparisonFunction(propertyName){
    return function(object1, object2){
        var value1 = object1[propertyName];
        var value2 = object2[propertyName];
    }
    if(value1 < value2){
        return -1;
    }else if(value1 > value2){
        return 1;
    }else{
        return 0;
    };
}

var data = [{name : "Zachary", age : 28}, {name : "Nicholas", age : 29}];

data.sort(createComparisonFunction("name"));
console.log(data[0].name);        //Nicholas

data.sort(createComparisonFunction("age"));
console.log(data[0].name);        //Zachary
5.4 函数内部属性

在函数内部,有两个特殊的对象:arguments和this

arguments有一个名叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数

function factorial(num){
    if(num <= 1){
        return 1;
    }else{
        return num * arguments.callee(num - 1);    //解除耦合
    }
}

函数内部的另一个特殊对象是this,this引用的是函数执行的环境对象——或者也可以说是this值(当在网页全局作用域中调用函数时,this对象引用的就是window)

ECMAScript5也规范化了另一个函数对象的属性:caller。这个属性中保存着调用当前函数的函数的引用,如果是在全局作用域中调用当前函数,它的值为null。

function outer(){
    inner();
}

function inner(){
    console.log(arguments.callee.caller);    //为了实现更松散的耦合
}

outer();

当函数在严格模式下运行是,访问arguments.callee会导致错误。ECMAScript 5 还定义了arguments.caller属性,但在严格模式下访问它也会导致错误,而在非严格模式下这个属性始终是undefined。定义arguments.callee属性是为了分清arguments.caller和函数的caller属性。以上变化都是为了加强这门语言的安全性,这样第三方代码就不能在相同的环境里窥视其他代码了。
严格模式还有一个限制:不能为函数的caller属性赋值,否则会导致错误。

5.5 函数属性和方法

每个函数都包含两个属性:lengthprototype

length:表示函数希望接受的命名参数的个数

prototype:对于ECMAScript中的引用类型而言,prototype是保存它们所有实例方法的真正所在

诸如toStr()和valueOf()等方法实际上都保存在prototype名下,只不过是通过各自对象的实例访问罢了。在ECMAScript 5 中,prototype属性是不可枚举的,因此使用for-in无法发现

每个函数都包含两个非继承而来的方法:apply()call()。这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值

apply():接收两个参数,第一个是在其中运行函数的作用域,第二个是参数数组

call():与apply()作用相同,变化在于传递给函数的参数必须逐个列举出来

在不给函数传递参数的情况下,使用哪个方法都无所谓

window.color = "red";
var o = {color : "blue"};

function sayColor(){
    console.log(this.color);
}

sayColor();                //red

sayColor.call(this);    //red
sayColor.call(window);    //red
sayColor.call(o);        //blue

使用call()(或apply())来扩充作用域的最大好处,就是对象不需要与方法有任何耦合关系

ECMAScript还定义了一个方法:bind()。这个方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值

window.color = "red";
var o = {color : "blue"};

function sayColor(){
    console.log(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor();        //blue

每个函数继承的toLocaleString()toString()valueOf()方法始终都返回函数的代码

6 基本包装类型

为了便于操作基本类型值,ECMAScript还提供了3个特殊的引用类型:Boolean、Number和String。这些类型与其他引用类型相似,但同时也具有与各自的基本类型相应的特殊行为。实际上,每当读取一个基本类型值得时候,后台就会创建一个对应的基本包装类型的对象,从而让我们能够调用一些方法来操作这些数据

var s1 = "some text";
var s2 = s1.substring(2);

进行以上操作,后台会自动完成以下一系列处理:

创建String类型的一个实例;

在实例上调用指定的方法;

销毁这个实例。

可以将以上三个步骤想象成是执行了下列ECMAScript代码:

var s1 = new String("some text");
var s2 = s1.substring(2);
s1 = null;

除非必要时,否则不推荐显式地调用Boolean、Number和String来创建基本包装类型的对象,因为这种做法很容易让人分不清自己是在处理基本类型还是引用类型的值。对基本包装类型的实例调用typeof会返回"object",而且所有基本包装类型的对象在转换为布尔类型时值都是true

Object构造函数也会像工厂方法一样,根据传入值的类型返回相应基本包装类型的实例:

var obj = new Object("some text");
console.log(obj instanceof String);        //true

使用new调用基本包装类型的构造函数,与直接调用同名的转型函数时不一样的:

var value = "25";
var number = Number(value);        //转型函数
console.log(typeof number);        //"number"

var obj = new Number(value);    //构造函数
console.log(typeof obj);        //"object"
6.1 Boolean类型

Boolean类型是与布尔值对应的引用类型

var booleanObject = new Boolean(true);

boolean类型的常见问题:

var falseObject = new Boolean(false);
var result = falseObject && true;
console.log(result);    //true

var falseValue = false;
result = falseValue && true;
console.log(result);    //false

console.log(typeof falseObject);        //object
console.log(typeof falseValue);            //boolean
console.log(falseObject instanceof Boolean);        //true
console.log(falseValue instanceof Boolean);        //false
6.2 Number 类型

Number类型是与数字值对应的引用类型

var numberobject = new Number(10);

可用toString()方法传递一个表示基数的参数,告诉它返回几进制数值的字符串形式

除了继承的方法(valueOf()、toLocaleString()、toString())外,Number类型还提供了一些用于将数值格式化为字符串的方法:

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

toExponential():该方法返回以指数表示法(e表示法)表示的数值的字符串形式。toExponential()也接收一个参数,指定输出结果中的小数位数

toPrecision():该方法可能会返回固顶大小(fixed)格式,也可能返回指数(exponential)格式;具体规则是看哪种格式最合适。这个方法接收一个参数,即表示数值的所有数字的位数(不包括指数部分)

6.3 String 类型

String类型是字符串的对象包装类型

var stringObject = new String("hello world");

String类型的每个实例都有一个length属性,表示字符串中包含多个字符

var stringValue = "杰神 ,shuai /" ";
console.log(stringValue.length);    //12

即使字符串中包含双字节字符(不是占一个字节的ASCII字符),每个字符也仍然算一个字符

7 单体内置对象

ECMA-262对内置对象的定义是:“由ECMAScript实现提供的、不依赖于宿主环境的对象,这些对象在ECMAScript程序执行之前就已经存在。”意思就是说,开发人员不必显式地实例化内置对象,因为它们已经实例化了。除了Object、Array和String等内置对象,ECMA-262还定义了两个单体内置对象:Global和Math

JavaScript原生对象及扩展

7.1 Global对象

Global(全局)对象可以说是ECMAScript中最特别的一个对象了,因为不管从什么角度上看,这个对象都是不存在的。不属于任何其他对象的属性和方法,最终都是它的属性和方法。诸如isNaN()isFinite()parseInt()以及parseFloat(),实际上都是Global对象的方法

Global对象还包含其他一些方法:

Global对象的encodeURI()encodeURIComponent()方法可以对URI(Uniform Resource Identifiers,通用资源标识符)进行编码,以便发送给浏览器

eval():该方法就像是一个完整的ECMAScript解析器,它只接受一个参数,即要执行的ECMAScript(或JavaScript)字符串

eval("alert("hi")");
//上行代码的作用等价于下面这行代码
alert("hi");

特殊的值undefined、NaN、以及Infinity都是Global对象的属性。此外,所有原生引用类型的构造函数,像Object和Function,也都是Global对象的属性。

ECMAScript 5 明确禁止给undefined、NaN和Infinity赋值,这样做即使在非严格模式下也会导致错误

7.1.4 window对象

ECMAScript虽然没有指出如何访问Global对象,但Web浏览器都是将这个全局对象作为window对象的一部分加以实现的。因此,在全局作用域中声明的所有变量和函数,都成为了window对象的属性

JavaScript中的window对象除了扮演ECMAScript规定的Global对象的角色外,还承担了很多别的任务

另一种取得Global对象的方法是使用以下代码:

var global = function(){
    return this;
}();
7.2 Math对象

ECMAScript还为保存数学公式和信息提供了一个公共位置,即Math对象。与我们在JavaScript直接编写的计算功能相比,Math对象提供的计算功能执行起来要快得多。Math对象中还提供了辅助完成这些计算的属性和方法

7.2.1 Math对象的属性

Math.PI:π的值

……

7.2.2 min()和max()方法

min()和Max()方法用于确定一组数值中的最小值和最大值。这两个方法都可以接收任意多个数值参数

7.2.3 舍入方法

Math.ceil()

Math.floor()

Math.round()

7.2.4 random()方法

random()方法返回大于等于0小于1的一个随机数。
套用下面的公式,就可以利用Math.random()从某个整数范围内随机选择一个值

值 = Math.floor(Math.random()) * 可能值的总数 + 第一个可能的值

var num = Math.floor(Math.random() * 9 + 2);    //介于2到10之间的值
function selectFrom(lowerValue, upperValue){
    var choices = upperValue - lowerValue + 1;
    return Math.floor(Math.random() * choices + lowerValue);

    var num = selectFrom(2, 10);
    console.log(num);    //介于2到10之间的值
}


var colors = ["red", "green", "blue"];
var color = colors[selectFrom(0, colors.lenght-1)];
console.log(color);        //可能是数组中包含的任何一个字符串

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/82431.html

相关文章

  • JS高程读书笔记--五章引用类型

    摘要:高程读书笔记第五章类型创建实例的方式有两种。第一种是使用操作符后跟构造函数,另一种方式是使用对象字面量表示法。 JS高程读书笔记--第五章 Object类型 创建Object实例的方式有两种。第一种是使用new操作符后跟Object构造函数,另一种方式是使用对象字面量表示法。 在通过对象字面量定义对象时,实际上不会调用Object构造函数 访问对象属性时可以使用点表示法和方括号表示法。...

    anRui 评论0 收藏0
  • 《Javascript高级程序设计 (第三版)》五章 引用类型

    摘要:类型没有重载声明了两个同名函数,而结果则是后面的函数覆盖了前面的函数。引用的是函数据以执行的环境对象函数属性和方法表示函数希望接收的命名参数的个数。而自动创建的基本包装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁。 Function类型 没有重载 声明了两个同名函数,而结果则是后面的函数覆盖了前面的函数。 var addSomeNumber = function (num)...

    GeekGhc 评论0 收藏0
  • 五章-Java修饰符#yyds干货盘点#

    摘要:修饰符包包的概述和使用其实就是文件夹作用对类进行分类管理包的定义格式格式包名多级包用分开范例带包的类编译和执行手动建包按照以前的格式编译文件手动创建包建立文件夹然后在下建立文件夹把文件放到包的最里面把文件放到下的这个文件夹下带包 1 修饰符1.1 包1.1.1 包的概述和使用其实就是文件夹作用:对类进行分类管理...

    caspar 评论0 收藏0
  • 《 JavaScript程序设计》—— 五章 函数总结及练习

    摘要:在编写处理对象的函数时,必须做出决定是希望这个函数修改其对象实参的的属性,还是返回新对象。高阶函数就是以形参或者返回函数的函数,他们可以简化集中程序设计任务,可以减少脚本中的共同代码数量。编写一个函数,返回一个给定字符在字符串中的出现次数。 主要总结: 函数值是一个带有参数的代码块,可以根据需要任意运行(调用) 调用一个函数,我们会向它的形参传送实参。多余的形参会被转换为undefi...

    genefy 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<