javascript高级程序设计第五章【下】(5.5-5.7)引用类型笔记

没看懂的地方1

5.5Function 类型

函数实际上是对象,而函数名实际上是一个指向函数(对象)的指针,所以一个函数其实可以有多个函数名
函数定义
函数定义一般使用函数声明语法定义

function sum(num1,num2){
     return num1 + num2;
}
console.log(sum(10,10));     //20

也可使用函数表达式定义函数,但要记得加;

var sum = function(num1 + num2){
    return num1 + num2;
};               //相当于定义一个变量并赋值,所以要加;

不推荐使用Function构造函数(这种语法会导致解析两次代码,一次解析常规的ECMAScript代码,一次解析传入的字符串)
函数名相当于一个指向函数(对象)的指针,函数名改变不影响函数

function sum(num1,num2){
    return num1 + num2;
}
var sum1 = sum;
console.log(sum1(10,10));   //20
sum = null;                 //改变sum的值,使其为空值  
console.log(sum1(10,10));   //20,sum的改变不会影响函数,此时他与函数已无关联
console.log(sum(10,10));    //会报错,因为sum此时已经不是函数了

5.51 没有重载(深入理解)

ECMAScript中的函数没有重载概念
先后声明两个同名函数,后面的函数会覆盖先前的函数

function addNum(num){
    return num + 10;
}
function addNum(num){
	return num + 20;
}
console.log(addNum(10));    //30

5.52函数声明与函数表达式

在代码被编译时,函数声明的函数有一个函数声明提升的过程,函数表达式没有

函数声明提升:对代码求值时,js引擎在第一遍会声明函数并将它们放到源代码树的顶部,所以即使声明函数在使用函数代码的后面,也可以吧声明函数提升到前面

console.log(addNum(10));    //30
function addNum(num){
    return num + 10;
}

函数表达式定义的函数只能将函数声明放在函数使用前面

console.log(addNum(10));    //报错:addNum is not a function
var addNum = function(num){
    return num + 10;
};

5.53作为值的函数

可像传递参数一样将一个函数传递给另一个函数,也可将一个函数作为另一个函数的结果返回
传递函数的指针

function callSomeFunction(someFunction,someArgument){
    return someFunction(someArgument);
}
function addTen(num){
    return num + 10;
}
var result1 = callSomeFunction(addTen,10);   
console.log(result1);                      //20

函数callFunction的第一个参数其实只是someFunction的函数名,并不是函数,若是函数的话那也不能将someFunction的参数改为someArgument了,也就失去了意义

5.54 函数内部属性

arguments对象
它是个类数组对象,包含着传入函数的所有参数。
它还有个名叫callee的属性,该属性是个指针,指向拥有arguments这个对象的函数。

function factorial(num){
    if(num <= 1){
        return num;
    }else{
		return num * factorial(num - 1);
	}
}

这是个阶乘函数,若函数有函数名且函数名不变那倒没有问题,但是如果没有函数或者函数名改变就会出问题了,所以改为第5行代码改为以下形式即可解决

        return num * arguments.callee(num - 1);

arguments对象的callee属性指向拥有对象的函数,即以上的factorial函数

this对象
函数总是指向调用函数的那个对象(自己写的)

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

function outer(){
    inner();
}
function inner(){
    console.log(inner.caller);           //function outer(){
}                                        //    inner();
outer();                                 //}

console.log()出了outer函数的源代码
为使得更松散的耦合,可以使用前面提到的arguments.callee代替函数名

    console.log(arguments.callee.caller);

5.55函数属性和方法

length属性
函数希望接收的命名参数的个数,例如sum(num1,num2)的length就是2

prototype属性
非常重要,第六章详细介绍

apply()方法
apply()接收两个参数:作用域(this),参数数组(arguments)
apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性.
相当于就是把另一个对象的属性拿来自己用
可以这样说
方法.apply(作用域,数组); //就是把一个方法在某个作用域下拿来作用到数组上

function Person(name,age){  
        this.name=name;  
        this.age=age;   
}  
/*定义一个学生类*/  
function Student(name,age,grade)  {  
        Person.apply(this,arguments);  
        this.grade=grade;  
}  
    //创建一个学生类  
var student=new Student("zhangsan",21,"一年级");     //使用函数给变量赋值时要使用new关键字
    //测试  
alert("name:"+student.name+"\n"+"age:"+student.age+"\n"+"grade:"+student.grade);  

上述例子就是用 Person.apply(this,arguments); 将Person里的name,age属性拿来给Student用

call()方法
用途大致一样,只是接受参数改了,第一个还是this,其余参数全部传给调用的函数,
借鉴连接

apply()方法和call()方法真正的用武之地是扩充函数赖以运行的作用域

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()方法取this,window,都是在全局作用域上,而最后一个引用对象o,将作用域扩充到了对象o上。
用apply(),call()扩充作用域的好处是对象不需要与方法有任何耦合关系

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

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

相当于创建了个新函数,等号左边是函数名,右边是原函数调用bind()方法,方法里的参数决定了原函数this指向哪个对象,决定了this的值
第六行代码等价于

var objectSayColor = function(){
    console.log(o.color);
}

每个函数继承的toLocaleString()和toString()方法始终都返回函数的代码。另外一个继承的valueof()方法同样也只返回函数代码

5.6基本包装类型

原文链接

5.6.1 Boolean类型(建议永远不要使用)

5.6.2 Number类型(不建议使用)

用到了再回来看这两种类型

5.6.3 String类型

String类型是字符串的对象包装类型,可用String构造函数来创建

var stringObject  = new String("hello world");    //好像是在后台这样创建包装对象

String对象的方法可在所有基本的字符串值中访问到,继承的valueof()、toLocalString()和toString()方法,都返回对象所表示的基本字符串值

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

var stringValue = "hello world";
console.log(stringValue.length);    //11

a.字符方法

charAt()
接受一个参数,字符位置,返回特定字符
charCodeAt()
接受一个参数,字符位置,返回特定字符的字符编码

var stringValue = "hello world";
console.log(stringValue.charAt(1));    //e
console.log(stringValue.charCodeAt(1));    //101

ES5定义了另一个识别个别字符的方法,有点类似数组用位置调用数组内的元素

var stringValue = "hello world";
console.log(stringValue[1]);    //e

b.字符串操作方法

concat()

将一个或多个字符串拼接起来,对原字符串无影响

var stringValue = "hello";
var result = stringValue.concat(" world");
var result1 = stringValue.concat(" world"," !");
console.log(result);    //hello world
console.log(result1);    //hello world !

其实和 + 差不多,不过实际操作中 + 用的更多些

slice(),substring(),substr()

都是由原字符串创建新的子字符串,三个方法都会接收一或两个参数,对原字符串无影响
三个方法的第一个参数都是子字符串的起始位置
slice(),substring()第二个参数都是最后一个字符后面的位置,substr()的第二个参数是返回的字符个数

var stringValue = "hello world";
console.log(stringValue.slice(2));    //llo world
console.log(stringValue.substring(2));    //llo world
console.log(stringValue.substr(2));    //llo world
console.log(stringValue.slice(2,7));    //ll0 w
console.log(stringValue.substring(2,7));    //llo w
console.log(stringValue.substr(2,7));    //llo wor

若传递给这些方法的参数是负值,slice()方法将传入的负值与字符串长度相加,substring()方法将所有负值转化为零,substr()方法将第一个负值参数与字符串长度相加,将第二个参数转化为零

var stringValue = "hello world";
console.log(stringValue.slice(-3));    //rld
console.log(stringValue.substring(-3));    //hello world
console.log(stringValue.substr(-3));    //rld
console.log(stringValue.slice(-3,-2));    //r
console.log(stringValue.substring(-3,-2));    // (空字符串)
console.log(stringValue.substr(-3,-4));    // (空字符串)

c.字符串位置方法

indexOf()从前往后查找,lastIndexOf()从后往前查找
都可接收两个参数,第一个参数是要查找的字符,第二个参数是查找的起始位置
找到了返回该字符位置,没找到则返回-1

var stringValue = "hello world";
console.log(stringValue.indexOf("o"));    //4
console.log(stringValue.lastIndexOf("o"));    //7
console.log(stringValue.indexOf("o",6));    //7
console.log(stringValue.lastIndexOf("o",6));    //4

可以运用循环加上这两种方法遍历将特定字符的位置全弄出来

var stringValue = "Lorem ipsum dolor sit amet, consectetur adipisicing elit";
var positions = new Array();
var pos = stringValue.indexOf("e");
while(pos > -1){
	positions.push(pos);    //将新得到的pos从数组尾部添加进数组
pos = stringValue.indexOf("e",pos + 1);
}
console.log(positions);    //[3,24,32,35,52]

不能用for,用for将每个位置当作起始位置查找效率太低,也不能用do{}while(),要考虑一开始就查找不到指定字符的情况

d.trim()方法

ES5定义的方法,创建一个字符串副本,删除前置和后缀的所有空格,然后返回结果。可用来对拥有较多无用空格字符串的改善

e.字符串大小写转换方法

toLowerCase() 将字符串中字符全转换为小写字符
toUpperCase() 将字符串中字符全转换为大写字符
toLocalLowerCase() 针对部分少数语言,将字符串中字符全转换为小写字符
toLocalUpperCase() 针对部分少数语言,将字符串中字符全转换为大写字符

在不知道代码将在哪种语言环境中运行的情况下,使用针对地区的方法更稳妥一些

f.字符串的模式匹配方法

match()方法
match()方法本质上与调用RegExp的exec()方法相同,返回匹配项的数组
只接受一个参数,要么是一个正则表达式,要么是一个RegExp对象

var text = "cat,hat,fat";
var pattern1 = /.at/;
var pattern2 = /.at/g;
var result1 = text.match(pattern1);
var result2 = text.match(pattern2);
console.log(result1);    //["cat"]
console.log(result2);    //["cat","hat","fat"]
console.log(result1.index);    //0   匹配项在数组中的位置
console.log(result2.index);    //undefined

search()方法
接收一个参数,要么是一个正则表达式,要么是一个RegExp对象
返回第一个匹配项的位置,没找到匹配项则返回-1

var text = "cat,bat,sat";
var pos = text.serch(/at/);
console.log(pos);    //1

replace()方法
接受两个参数,第一个是要被替换的字符串或者正则表达式,第二个参数是要替换上去的字符串或者是一个函数

var text = "cat,hat,fat";
var result1 = text.replace("at","xx");
var result2 = text.replace(/at/g,"xx");
console.log(result1);    //cxx,hat,fat
console.log(result2);    //cxx,hxx,fxx

第一个参数是字符串则只能替代第一个匹配项,若需要替代所有匹配项,则需要用正则表达式,且是g模式,注意正则表达式不需要加引号
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
如果第二个参数是字符串,那么还可以使用一些特殊的字符序列,将正则表达式得到的值插入到结果字符串中

字符序列替换文本
$$$
$&匹配整个模式的字符串
$’匹配的字符串之前的子字符串
$`匹配的字符串之后的子字符串
$n匹配第n(0~9)个捕获组的子字符串,若正则表达式未定义捕获组,则使用空字符串($n)
$nn匹配第nn(0~99)个捕获组的字符串
var text = "cat,hat,fat";
var result1 = text.replace(/(.at)/g,"world($1)");
var result2 = text.replace(/.at/g,"world($1)");
console.log(result1);    //world(cat),world(hat),world(fat)
console.log(result2);    //world($1),world($1),world($1)

split()方法
基于指定的分割符将一个字符串分割成多个字符串,并将结果放在一个数组中
接受的第一个参数是分隔符,可接受第二个参数,用于指定数组的大小

var text = "cat,hat,fat,nat";
var text1 = text.split(",");
var text2 = text.split(",",2);
console.log(text1);    //["cat","hat","fat","nat"]
console.log(text2);    //["cat","hat"]

g. localeCompare()方法

比较两个字符串,并返回一个值

字符串和字符串参数的比较返回的值
字符串首字母在字符串参数首字母之前负数(大多数是-1)
字符串等于字符串参数0
字符串首字母在字符串参数首字母之后正数(大多数是1)
var text = "lili";
var text1 = "zizi";
var text2 = "lili";
var text3 = "aiai";
console.log(text.localeCompare(text1));    //-1
console.log(text.localeCompare(text2));    //0
console.log(text.localeCompare(text3));    //1

可以创建一个比较两字符串的函数

var stringValue = "yellow";
function determinOrderValue(value){
	var result = stringValue.localeCompare(value);
	if(result < 0){
		console.log(stringValue + " is before than " + value);
	}else if(result > 0){
		console.log(stringValue + " is after than " + value);
	}else{
		console.log(stringValue + " is equal than " + value);
	}
}
determinOrderValue("aaaa");    //yellow is after than aaaa
determinOrderValue("yellow");    //yellow is equal than yellow
determinOrderValue("zzzzz");    //yellow is before than zzzzz

h. fromCharCode()方法

接受一或多个字符编码,将其转化为一个字符串

console.log(String.fromCharCode(104,101,108,108.111));    //hello

5.7单体内置对象

由ECMAScript实现提供的,不依赖于宿主环境的对象,这些对象在ECMAScript程序执行之前就已经存在了
开发人员不需要实例化内置对象,因为他们已经实例化了
Object,Array,String就是内置对象,还有两个单体内置对象:Global和Math

5.7.1 Global对象

不属于任何其他对象的属性和方法,最终都是Global对象的属性和方法
所有在全局作用域中定义的属性和函数,都是Global对象的属性

1.URI编码方法(没看懂,回来再看)

什么是URI
encodeURI()和encodeURIComponent()可以对URI进行编码,以便发送给浏览器
encodeURI()不会对本身属于URI的特殊字符进行编码

2. eval()方法

只接受一个参数,要执行的ECMAScript或js字符串
调用eval()方法时,会将传入的参数当作实际的ECMAScript语句来解析,然后把执行结果放到原位置
eval()执行的代码可以引用在包含环境中定义的变量,函数

var msg = "hello world";
eval("console.log(msg);");

但是在eval()中创建的任何变量或函数都不会被提升,只有先定义再引用才可以

eval("console.log(msg);");    //报错
var msg = "hello world";    
console.log(msg);    //undefined
var msg = "hello world";    

在严格模式下为eval赋值也会导致错误

5.7.2 Math对象

保存数学公式和信息的公共位置

1.Math对象的属性

部分常用属性

属性说明
Math.E自然对数的底数,常量e的值
Math.LN10ln10,(其他对数都可这样推)
Math.LOG2E以2为底e的对数
Math.PIΠ的值
Math.SQRT1_21/2的平方根
Math.SQRT22的平方根

2.min()和max()方法

确定一组数的最小值和最大值

var max = Math.max(3,8,7,6);
var min = Math.min(3,8,7,6);
console.log(max,min);    //8 3

确定一个数组的中数字的最大值

var values = [1,2,3,4,5,6];
var max = Math.max.apply(Math,values);  
console.log(max);    //6

用了apply()方法,忘了apply()方法就点这里,Math.max()方法是确定一组数的最大值,Math是总的作用域,values是要执行方法的数组,所以就是在Math作用域内将Math.max()方法作用到values这个数组上
(未完待续)

3.舍入方法

Math.ceil() 总是将小数向舍入为最接近的整数
Math.floor() 总是将小数向舍入为最接近的整数
Math.round() 对小数四舍五入

console.log(Math.ceil(25.1),Math.ceil(25.5),Math.ceil(25.9));    //26,26,26
console.log(Math.floor(25.1),Math.floor(25.5),Math.floor(25.9));    //25,25,25
console.log(Math.round(25.1),Math.round(25.5),Math.round(25.9));    //25,26,26

4.random方法

Math.random()方法返回大于0,小于1的一个随机数
从某个整数范围内随机选取一个值

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

随机取1到50中任意整数,取50个这样的整数

for(var i = 1;i <= 50;i++){
    var num = Math.floor(Math.random() * 50 + 1);
	console.log(num);
}

创建一个随机从某数到某数之间取整数的函数,并且用这个函数来随机取一个数组的一项

function selectNum(lowerNum,upperNum){
    var num = upperNum - lowerNum + 1;    //计算可能取到的值的个数
    return Math.floor(Math.random() * num + lowerNum);    
}
var colors = ["red","black","white","green","pink","yellow"];
var selectColor = colors[selectNum(0,colors.length - 1)];    //调用selectNum函数确定随机取得selectColor的位置
console.log(selectColor);

5.其他方法

方法说明方法说明
Math.abs(num)num的绝对值Math.asin(x)x的反正弦值
Math.exp(num)Math.E的num次幂Math.atan(x)x的反正切值
Math.log(num)num的自然对数Math.asin2(y,x)y/x的反正切值
Math.pow(num,power)num的power次幂Math.cos(x)x的弦值
Math.sqrt(num)num的平方根Math.sin(x)x的正弦值
Math.acos(x)num的反余弦值Math.tan(x)x的正切值
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值