本文继续对js的基础知识进行学习。

一、日期操作

对于日期一般都是简单的显示,因为处理都是在后端的。

1
2
3
4
5
6
7
8
9
10
11
12
13
<script type="text/javascript">
//获取当前时间
var now = new Date();
console.log(now);//当前时间:Wed Mar 20 2019 14:58:09 GMT+0800 (中国标准时间)

//也可以自定义时间
var time = new Date("2019-03-20 15:04:14");
console.log(time);

//可以set也可以get
console.log(now.getDay());
console.log(now.getMonth());//注意0代表的是一月份
</script>

二、字符串的一些操作

1
2
3
4
5
6
7
8
9
10
<script type="text/javascript">
//字符串处理
var str = "HELLO fossi";
//str = str.replace("o","O");//替换o为O
str = str.replace(/o/gi,"e");//g全局,i表示忽略大小写,这里用到了正则表达式
console.log(str);
str = "HELLO fossi";
var res = str.split(" ");//按照空格进行切割,返回的是数组
console.log(res);// ["HELLO", "fossi"]
</script>

关于字符串的操作有很多很多,且与其他主流语言支持的差不多,所以就不赘述了。

三、函数的调用和声明位置

一般情况下,函数是先定义再调用。但是在js中如果是普通的函数,那么无论是先声明再调用还是先调用再声明,都是可以的。

1
2
3
4
5
6
7
8
9
10
11
<script type="text/javascript">
//1.先调用函数,再声明函数
console.log(add1(2,3));//OK

function add1(num1,num2){
return num1+num2;
}

//2.先声明函数再调用
//console.log(add1(2,3));//OK
</script>

但是另一种方式,就是一个函数作为一个变量的写法,就必须先声明再调用了。

1
2
3
4
5
6
7
8
9
10
<script type="text/javascript">
console.log(add2(2,3));//ERROR

//作为一个变量的话,必须先声明后使用
var add2 = function(num1,num2){
return num1+num2;
}

//console.log(add2(2,3));//OK
</script>

四、函数作为参数传递

js非常灵活,一个函数就可以作为参数传递进另一个函数中。例如:

1
2
3
4
5
6
7
8
9
10
11
12
<script type="text/javascript">
//函数可以作为参数传递给另一个函数
function addTen(num){
return num+10;
}

function callFuntion(someFuntion,arg){
return someFuntion(arg);
}

console.log(callFuntion(addTen,100));//110
</script>

五、根据属性对对象进行排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<script type="text/javascript">
// 自定义的排序
var person1 = {
name:"fossi",
age:20
};

var person2 = {
name:"swg",
age:30
};

var person3 = {
name:"swg",
age:25
};

var arr = [person1,person2,person3];
//用createComparator进行排序的定义
console.log(arr.sort(createComparator("age")));

function createComparator(propertyName){
return function(obj1,obj2){
var value1 = obj1[propertyName];
var value2 = obj2[propertyName];
if(value1 > value2){
return 1;
}else if(value1 < value2){
return -1;
}else{
return 0;
}
}
}
</script>

六、apply和call

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script type="text/javascript">
// apply call
function sum(num1,num2){
return num1+num2;
}

function callSum(num1,num2){
//1.第一种写法
// return sum.apply(this,arguments);
//2.第二种写法
return sum.apply(this,[num1,num2]);
}

console.log(callSum(2,3));

function callSum2(num1,num2){
return sum.call(this,num1,num2);
}

console.log(callSum2(2,3));
</script>

applycall方法类似,简单理解,都是相当于调用其他的方法。它有个显著的特点就是改变作用域,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
<script type="text/javascript">
//可以改变作用域
var color = "red";
var person = {color:"green"};

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

showColor();//red
showColor.apply(person);//green
showColor.call(person);//green
</script>

直接调用必然是全局域中的red,但是用apply方法的话,传禁区的是person这个对象,那么此时打印出来的就是这个对象中的属性值。

七、包装类型

1
2
3
4
5
6
7
8
9
10
11
<script type="text/javascript">
//基本类型的包装类型
var s = "hello fossi";
// 等价于:var s = new String("hello fossi");
var res = s.split(" ");
console.log(res);

//但是一旦包装类型创建成功后就不能再像普通对象一样添加属性
s.name = "fossi";
console.log(s.name);//undefined
</script>

包装类型可以提供一些方法让你调用,十分方便。上面说的是字符串,还有布尔和number类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script type="text/javascript">
var falseObj = new Boolean(false);//尽量不要用,会引起一些必要的问题
var fal = false;
console.log(typeof falseObj);//object
console.log(typeof fal);//boolean

//number类型
var numberObject = new Number(10);
var number = 10.005;
console.log(number.toFixed(2));//指定显示的小数的位数,这里就是10.01
var number2 = 2374281472;
console.log(number2.toExponential());//指数来表示
console.log(number2.toPrecision(3));//自己指定位数显示
</script>

八、eval

这玩意可就厉害了,可以把js的语句包在字符串里面,可以直接执行和调用,如下所示:

1
2
3
4
5
6
7
8
<script type="text/javascript">
//可以在eval里面嵌套语句或者函数
var a = "hello world";
eval("console.log(a)");//hello world

eval("function say(){alert(a)}");
say();//hello world
</script>

九、面向对象

我们知道定义一个对象,如果没有任何处理的话,可以直接修改它的属性:

1
2
3
4
5
6
7
8
9
<script type="text/javascript">
var person = {
name: "fossi",
age: 20,
sex: 1
}

person.name = "swg"; //如果不让随意做修改怎么办呢?
</script>

此时就需要给它加上一些规则,允许对它干什么,不允许对它干什么,都规定好。那么如果不允许对它的属性进行修改的话,那么就不能通过上面的方式进行随意修改了,这如何实现的呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script type="text/javascript">
var person = {
name: "fossi",
age: 20,
sex: 1
}

console.log(Object.getOwnPropertyDescriptor(person,"name"));
//主要显示的是四个属性:
//{value: "fossi", writable: true, enumerable: true, configurable: true}
//value:值;
//writable是否可以修改;
//enumerable是否支持for-in遍历;
//configurable是否允许删除
</script>

下面我们来实际操作一下这几个属性。

首先我配置它不允许被删除,下面再删除属性试试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script type="text/javascript">
var person = {
name: "fossi",
age: 20,
sex: 1
}

//数据属性-控制对象的数据
Object.defineProperty(person,"name",{
configurable:false,//不允许删除此属性
value:"swg"
});
console.log(person.name);//swg
delete person.name;
console.log(person.name);//没有报错,还是swg

</script>

下面配是一下不能修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script type="text/javascript">
var person = {
name: "fossi",
age: 20,
sex: 1
}

//数据属性-控制对象的数据
Object.defineProperty(person,"name",{
configurable:false,//不允许删除此属性
writable:false
});
console.log(person.name);//fossi
person.name = "swg";
console.log(person.name);//fossi
</script>

修改不成功,说明不让在外面修改了。好了,关于数据属性就介绍这么多,下面说一下访问器属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script type="text/javascript">
var person = {
name: "fossi",
_age: 0,
sex: 1,
birth:1994
}

//数据属性-控制对象的数据
Object.defineProperty(person,"age",{
get: function(){
return this._age = 2019-this.birth;
},
set: function(newVal){
this._age = newVal;
}
});
console.log(person.age);//25
</script>

就是说一调用person.name的时候就会自动调用get来获取,这里就可以实现动态的获取年龄。

注意,这里的age用_age代替.前面加下划线是常用的用法,表示只能用对象方法访问的属性.如果用age回导致死循环赋值.

比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script type="text/javascript">
var person = {
name: "fossi",
age: 0,
sex: 1,
birth:1994
}

//数据属性-控制对象的数据
Object.defineProperty(person,"age",{
get: function(){
return this.age = 2019-this.birth;
},
set: function(newVal){
this.age = newVal;
}
});
console.log(person.age);//25
</script>

显示:

1
2
3
4
5
6
7
8
9
test.html:22 Uncaught RangeError: Maximum call stack size exceeded
at Object.set [as age] (test.html:22)
at Object.set [as age] (test.html:22)
at Object.set [as age] (test.html:22)
at Object.set [as age] (test.html:22)
at Object.set [as age] (test.html:22)
at Object.set [as age] (test.html:22)
at Object.set [as age] (test.html:22)
at Object.set [as age] (test.html:22)