JavaScript基础课程

第二讲

类和对象

  类可以看成一个工厂,我规定了这个工厂里要生产的东西,其实就是生成的对象,东西的大小,样式等,就相当于对象的属性,我们定义好一个类后,生成的对象就有了那些属性。

但是,在JS里没有类这个东西,就是说我们没有一个明确的语法来声明一个类,但是我们可以通过JS其他的方法达到这个目的,这个知识内容较复杂,我们不讲,想在前端继续走下去的以后需要私下里去看,JS里是有对象这个概念的,就是我们下面要讲的内容

引用类型

  1. Object
  2. Array
  3. Date
  4. RegExp
  5. Function
  6. 基本包装类型

JS里的对象是引用类型

这几个类型是JS已经封装好的,大家可以把他们看成是类

什么是引用?

其实就是一个对象的别名

var a  = {};

b = a;

b.name = "SIPC";

console.log(a.name);      // SIPC

Object类型

  • 对象的声明
  • 对象属性的操作
  • prototype
  • Object是所有对象的父类

对象的声明

//   字面量声明法 (推荐)

var organization = {
    name: "SIPC",
    age: 6
}

//   new操作符 

var organization = new Object();
organization.name = "SIPC";
organization.age = 6;

对象属性的操作

//  声明属性
var person = {};
person.name = "jorten";
person.age = 19;

//  访问属性
console.log(person.name);   //点表示

console.log(person["name"]);  //方括号表示

//特殊形式的需要用方括号表示

person["first name"] = "xia";

//JS中字符串可以用""表示也可以用''表示

//  删除属性

delete person['name'];

prototype

像我们刚才说的,一个类要定义生成对象的一些属性,那怎么保存这些属性呢?就是用prototype

Object.prototype.age = 20;

var person = {};

console.log(person.age); //20

Object 的 prototype

  • toString
  • valueOf
  • constructor

所有对象是的Object的子类

子类就是说它生成的对象有了父类的属性和方法,所以我们生成的对象不用定义属性就有刚才提到的属性和方法

var a = new Object();

console.log(a.toString());

//     [object Object]

Object.toString.call(obj)

判断一个对象的类型

var arr = new Array();
console.log(Object.prototype.toString.call(arr));
//  [object Array]

console.log(typeof arr);
//  object

console.log(arr instanceof Array);
//  true

console.log(arr instanceof Object);
// true

var reg = new RegExp();
console.log(Object.prototype.toString.call(reg));
//  [object RegExp]

Array

  • 数组的声明及操作
  • join
  • length
  • push、pop
  • shift、unshift
  • reverse、sort
  • concat
  • slice
  • splice
  • indexOf、lastIndexOf
  • 迭代
  • 归并

数组的操作

声明数组 :

//  字面量(推荐)
var arr1 = [1, 2, 3]

//  new方法
var arr2 = new Array();
var arr3 = new Array("Jorten");
var arr4 = new Array(1, 2, 3);
var arr5 = new Array(20);

操作数组 :

var arr = [1, 2, 3];
console.log(arr[0])  
// 1

arr[3] = 4;
console.log(arr);
// [1, 2, 3, 4]

conosole.log(arr[10])
// undefined

数组里的元素可以是任意类型的

var arr = [];

arr[0] = undefined;

arr[1] = 1;

arr[2] = new Object();

arr[3] = [1, 2, 3];

arr[4] = "sipc"

console.log(arr);

// undefined, 1, Object, Array(3), "sipc"

join

使用分隔符来构造字符串

var arr = ['red', 'green', 'blue'];
console.log(arr.join(', ');
// red, green, blue

console.log(arr.join('|');
// red|green|blue

console.log(arr.join('');
// redgreenblue

console.log(arr.join(undefined));
// red,green,blue

console.log(arr.join());
// red,green,blue

//如果不传值或传入undefined  默认使用逗号作为分隔符

length

表明一个数组的长度

var arr = [1, 2, 3]
console.log(arr.length);
// 3

可以通过修改length来改变数组

var arr = [1, 2, 3, 4]
arr.length = 3;
console.log(arr);
//  [1, 2, 3]
console.log(arr[3]);
//  undefined

var arr = [];
arr.length = 2;
console.log(arr);
// [undefined, undefined]  未赋值的项全为undefined

var arr1 = [1, 2, 3];
arr1[99] = 100;
console.log(arr1.length);
//  100    未赋值的项全为undefined

push  、pop 

push:在数组的结尾加上一个元素

var arr = [1, 2];
arr.push(3);
console.log(arr);
// [1, 2, 3]

pop:删去数组的结尾元素

var arr = [1, 2, 3];
arr.pop();
console.log(arr);
// [1, 2]

shift  、unshift

shift:删去数组的第一个元素

       unshift:在开头添加一个元素

var arr = [1, 2];
arr.shift();
console.log(arr);
// [2]
var arr = [1, 2];
arr.unshift(0);
console.log(arr);
// [0, 1, 2]

reverse  、sort

reverse:将数组倒序

var arr = [1, 2, 3];
arr.reverse();
console.log(arr);
//  [3, 2, 1]

sort:将数组升序排列

var arr = [2, 3, 1, 5, 4];
arr.sort();
console.log(arr);
//  [1, 2, 3, 4, 5]

//  注意
var arr = [2, 4, 10, 14];
arr.sort();
console.log(arr);
//  [10, 14, 2, 4]

//  说好的升序排列呢?

sort排列方法

默认的sort方法是比较字符串的大小的,而在字符串的大小比较中"14" < "2", 因为字符串的比较会先从他们的第一个字符开始比较他们的Unicode码,咱们这里可以看作数字的ASCII码,因为1的ASCII码小于2,所以"14" < "2",

如果第一个字符相同,就一直往下比较,如果全相等就相等

console.log(14 < 2);

//  false

console.log("14" < "2");

//  true

console.log("1" < "11");

//  true

那么如何让sort真正的升序排列?

sort是可以传参数的

sort里可以传入一个比较函数作为参数

比较函数里有两个参数

返回负数第一个参数在第二个参数之前

返回0两个参数相等

返回正数第一个参数在第二个参数之后

我们传入比较函数后就可以让数组的每一项进行两两比较了

sort升序可以这样写

var arr = [2, 11, 14, 4, 1];
arr.sort(function(val1, val2) {
    if(val1 < val2) {
        return -1;
    } else if(val1 === val2) {
        return 0;
    } else {
        return 1;
    }
});
console.log(arr);

//  [1, 2, 4, 11, 14]

//  更简单的写法

arr.sort(function(val1, val2) {
    return val1 - val2;
});

console.log(arr);

//  [1, 2, 4, 11, 14]

concat

拼接数组,传入一个或多个数组作为参数,如果不是数组则直接添加,注意和前面不同的是原数组不变,返回值为拼接的数组

var arr1 = [1, 2, 3];

var arr2 = arr1.concat(4, [5, 6]);

console.log(arr1);

// [1, 2, 3]

console.log(arr2);

//[1, 2, 3, 4, 5, 6]

slice

对数组进行切割,截取原数组的一部分

 

var arr = [1, 2, 3, 4];

var arr2 = arr.slice();

console.log(arr);

//  [1, 2, 3, 4]

console.log(arr2);

//  [1, 2, 3, 4]

arr2 = arr.slice(1);

console.log(arr2);

//  [2, 3, 4]

arr2 = arr.slice(1, 3);

console.log(arr2);

//  [2, 3]

splice

var arr1 = [1, 2, 3, 4];

arr1.splice(1, 1);

console.log(arr1);

//  [1, 3, 4]

arr1.splice(1, 0, 1.5);

console.log(arr1);

//  [1, 1.5, 3, 4]

arr1.splice(2, 1, 2);

console.log(arr1);

//  [1, 1.5, 2, 4]

arr1.splice(1, 0, 7, 9);

console.log(arr1);

//  [1, 7, 9, 1.5, 2, 4]

indexOf、lastIndexOf

返回目标的索引值

var arr = [1, 2, 3, 4, 5, 4, 3, 2, 1];

console.log(arr.indexOf(2));

//  1

console.log(arr.indexOf(2, 2));

//  7

console.log(arr.indexOf(123));

//  -1

console.log(arr.lastIndexOf(2));

//  7

console.log(arr.lastIndexOf(2, 4));

//  1

迭代

  • every:每一项为true返回true
  • filter:返回返回true的项的数组
  • forEach:无返回值对每一项运行函数
  • map:返回每一项运行结果的数组
  • some:有一项返回true则返回true

传入一个函数作为参数

函数有三个参数:数组项的值,改项在数组中的位置,数组对象本身

reduce

归并方法

迭代所有项返回最终值

传入一个函数和一个基础值

函数有4个参数,为前一个值,当前值,项的索引,数组对象

var values = [1, 2, 3, 4, 5];

var sum = values.reduce(function(prev, cur, index, array) {

    return prev + cur;

}, 10);

console.log(sum);

//  25

//  第二个参数没有则以0开始

类数组

有着和数组一样的元素分布,可以像操作数组一样操作他们,也有length属性,但是没有数组的其他方法,如push等

上节课讲的arguments以及以后要讲的HTMLDOM数组就是这样的类数组

类数组转化为数组的方法:

var arr1 = [].slice.call(arr);

Date

声明一个日期对象

var now = new Date()

now = new Date("March 20, 2016")

now = new Date(1231535161);

Date.parse(now)

返回此时间到1970年1月1日零点的毫秒数

Date.now()

返回现在到1970年1月1日零点的毫秒数

Date.UTC(2016, 2, 20,17, 55, 55)

返回2016年3月20日17:55:55到1970年1月1日零点的毫秒数

Date的方法

  • toDateString
  • toTimeString
  • toLocaleDateString
  • toLocaleTimeString
  • toUTCString
  • toLocaleString
  • set/getTime
  • set/get(FullYear/Month)
  • set/get(Date/Day)
  • set/get(Hours/Minutes/Seconds)

RegExp

var pattern = /at/g;

var pattern = new RegExp("at", "g");

g:全局模式

i:不区分大小写

m:多行模式

用来匹配字符串

exec

var text = "mom and dad and son";

var pattern = /[a-z]d/gi;

var matches = pattern.exec(text);

console.log(matches);

//  ["nd", index: 5, input: "mom and dad and son"]

matches = pattern.exec(text);

console.log(matches);

//  ["ad", index: 9, input: "mom and dad and son"]

index代表索引的位置,input代表匹配的字符串

Function

  • 函数声明
  • 函数表达式
  • this
  • call、apply
  • bind
  • callee、caller

函数声明

function sayName(obj) {
    console.log(obj.name);
}


//  匿名函数
var sayColor = function(obj) {
    console.log(obj.color);
}        


//  不推荐
var sayAge = new Function("obj", "console.log(obj.age)");

函数表达式

//  函数声明完立即调用可以吗?

function sayHi() {
    console.log("Hi");
}();

//  会报错,因为浏览器会把它当成函数声明  是不能执行的

(function sayHi() {
    console.log("Hi");
})();

//  可以,因为这是函数表达式  可以执行

this

this指的是函数执行的环境对象

var a = {
    color: 'red'
}

var color = 'yellow';

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

sayColor();

//  yellow

//  因为在全局作用域上调用的函数,所以this指向的是全局对象window

call、apply

var a = {
    color: 'red'
}

var color = 'yellow';

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

sayColor.call(a);


//  red

//  this指向了a对象



改变this的指向,在特定作用域调用函数

不同之处为函数参数传入的形式

bind

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

var a = {
    color: 'red'
}

var color = 'yellow';

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

var sayColorA = sayColor.bind(a);

sayColorA();

//  red

callee  、caller

arguments有一个callee属性:指向拥有这个arguments的函数

函数的caller属性:保存着调用当前函数的函数的引用

function inner() {
    console.log(arguments.callee.caller);
}

function outer() {
    inner();
}

outer();

基本包装类型

  1. Boolean
  2. Number
  3. String
  4. global
  5. window
  6. Math

Boolean、Number

Boolean()

Number()

将目标转成布尔值/数字

num.toString([2, 8, 10, 16])

num.toFixed(2)

console.log(Boolean(2));

//  true

console.log(Number([1, 2]));

//  NaN

console.log(1.004.toFixed(2));

//  1.00

String

  • charAt、charCodeAt
  • concat、slice
  • indexOf、lastIndexOf
  • trim
  • toUpperCase、toLowerCase
  • match
  • split

字符串可以索引

var str = "hello world";

console.log(str[0]);

//  h

str[1] = "a";

console.log(str);

//  hallo world

JS中的字符串可以用""也可以用''表示,

但是要统一

charAt  、charCodeAt

charAt:返回第i个字符

charCodeAt:返回第i个字符的Unicode码

var str = "Hello World";

console.log(str.charAt(0));

//  H

console.log(str.charCodeAt(3));

//  108

concat

var str1 = "hello";

var str2 = str1.concat(" ", "world", "!");

console.log(str2);

//  hello world!

console.log(str2.slice(6));

//  world!

和数组一样,拼接和切割

indexOf  、lastIndexOf

和数组一样索引

var str = "hello world";

console.log(str.indexOf("llo"));

//  2

console.log(str.indexOf("o"));

//  4

console.log(str.lastIndexOf("o"));

//  7

trim

删除字符串开头和结尾的字符串

var str = "   hello world   ";

var str1 = str.trim();

console.log(str1);

//  hello world

toUpperCase

toLowerCase

将字符串变为大写/小写

var str = "Hello World";

console.log(str.toUpperCase());

//  HELLO WORLD

console.log(str.toLowerCase());

//  hello world

match

匹配字符串

var text = "cat, bat, sat, fat";

var pattern = /at/;

console.log(text.match(pattern));

//  ["at", index: 1, input: "cat, bat, sat, fat"]

split

按照所传参数分割字符串成数组

var str = "1, 2, 3, 4, 5";

console.log(str.split(", "));

//  ["1", "2", "3", "4", "5"]

console.log(str.split(""));

//  ["1", ",", " ", "2", ",", " ", "3", ",", " ", "4", ",", " ", "5"]

console.log(str.split());

//  ["1, 2, 3, 4, 5"]

Global  、window

  • eval
  • isNaN
  • isFinite
  • parseInt
  • parseFloat

              eval("alert('hello')");

Math

  • min、max
  • ceil
  • floor
  • round
  • random
  • abs

下节课预告

  • 变量提升
  • 函数提升
  • 函数闭包
  • BOM