面向对象
1.String类型(常用)
length 属性,获取字符串的字符量 str.length---属性 str.length()---方法
charAt(i) 返回给定位置的字符
charCodeAt(i) 返回指定位置字符的编码
indexOf("x") 查找指定字符所在位置 如果字符存在,返回的是字符存在位置,如果不存在,返回-1
有一个数字类型的可选参数,代表从哪个位置开始查找。
lastIndexOf("") 从后往前找,查找字符所在位置 (字符的位置不会变,比如hello从后往前找e 返回值是1,不是3) 跟indexOf("")一样
concat() 作用:拼接字符串的一个方法
串拼接起来,返回值是新字符串,大部分内情况 使用 + 去替代该方法
调用者:str1
参数:str2
返回值:str1+str2
slice 作用:截取指定字符串 [start end) 左闭右开[)
不改变原始值,所以注意使用新变量接收的结果 console.log(s.slice(3,7));//3-6 不包括7
返回值:string
substr() 参数:开始位置找from,截取长度找length (from,length)
返回值:string
不会改变原始值
substring (start end) 开始位置start,结束位置end
不会改变原始值
作用:截取指定字符串 [start end) 左闭右开[)
返回值:string
trim() 作用:删除字符串前后空格 中间不管,只管前后空格
返回值:被处理过得字符串
toUpperCase 所有字母转换为大写
toLowerCase 不管之前你是小写还是大写,所有字母都会被转换成为小写
2.Math对象 常用方法:
Math.min(): 找一组数中,最小的值;
作用: 返回一组数中的最小值
Math.max(): 找一组数中,最大的值;
Math.ceil(): 向上取舍 console.log(Math.ceil(10.41)); //11
Math.floor(): 向下取舍 console.log(Math.floor(10.91)); //1
Math.round(): 四舍五入 console.log(Math.round(10.41)); //10
console.log(Math.round(10.91)); //11
Math.random(): 返回值是在(0,1)之间的一个随机数
其他方法
abs(num) 绝对值
exp(num) 返回Math.E的num次幂
log(num) 返回num的自然对数
pow(num,power) 返回num的power次幂
3.Date对象
var date = new Date();
常用方法:
getFullYear() 返回日期对象中的年份;
getMonth() 月份 0-11 一月-12月
getDate() 返回日期对象中的几号;
getDay() 返回星期几 周日开始0 周一-周六 1-6
getHours() 返回小时 0-23点
getMinutes() 返回分钟 0-59分
getSeconds() 返回秒 0-59秒
getMilliseconds() 返回毫秒
getTime() 时间初 1970年01月01日 午夜到现在的毫秒数
date.valueOf()
date.getYear() 当前年份-1900
date.toDateString() 以字符串的形式返回一个Date的日期部分
date.toTimeString() 中国标准时间
date.toISOString()
console.log(date.toISOString());//2021-09-02T03:19:22.428Z
date.toJSONString()
console.log(new Date(jsonDate).toUTCString()); // expected output: Tue, 19 Aug 1975 23:15:30 GMT
date.toString()
4.Date
function dateFMT (date) {
// var date = new Date();
var y = date.getFullYear();
var m = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
var d = date.getDate().toString().padStart(2, "0");
var hh = date.getHours().toString().padStart(2, "0");
var mm = date.getMinutes().toString().padStart(2, "0");
var ss = date.getSeconds().toString().padStart(2, "0");
return y + "-" + m + "-" + d + " " + hh + ":" + mm + ":" + ss;
}
console.log(dateFMT(new Date()));
5.对象的创建
//普通模式 一般对象的创建:
var obj1 = {
name:"zhngsan",
age:12,
gender:男,
sayName:function(){
console.log(this.name);
}
}
var obj2 = {
name:"ls",
age:12,
gender:男
}
由上述 多种东西重复使用 —》有了工厂模式:封装一个方法
5.1工厂模式
因为使用普通的字面量创建多个对象时,会产生大量的重复代码,为了解决这个问题,我们引入工厂模式。
目的:通过将创建对象的方法封装起来,避免重复代码的产生。
//工厂模式
function newPerson(name,age,gender){
var p = new Object();
p.name = name;
p.age = age;
p.gender = gender;
p.sayName = function(){
console.log(this.name);
}
return p;//返回p值
}
var p1 = newPerson('zhangsan',12,'男');
var p2 = newPerson('lisi',15,'女');
console.log(p1,p2);//检验p1 p2
p1.sayName();//执行函数
p1.sayName();
function newDog(name,age,gender){
var d = new Object();
d.name = name;
d.age = age;
a.gender = gender;
d.sayName = function(){ //每个对象都会有一个这个sayName方法
console.log("汪汪的名字是"+this.name);
}
return d;
}
var d1 = newDog("wangzai",2,"男");
console.log(d1);
d1.sayName();
console.log(typeof p1);//object
console.log(typeof d1);//object
工厂模式创建对象的缺点:创建的所有对象类型都是Object类型,没有办法知道对象到底是Person还是Dog.
5.2构造函数模式
function Person(name,age,gender){ //person类
this.name = name;
this.age = age;
this.gender = gender;
this.sayName = function(){
console.log('this.name');
}
}
var p1 =new Person('terry',23,'男');
p1.sayName();
console.log(p1);
console.log(typeof p1);
构造函数的问题:
- 可以区分每个类
- 每个方法都要在 每个实例上重新创建一遍,么有必要
- 虽然可以将方法提取出来,提取到全局范围内,然后将引用传递给对象中的函数属性,但是全局函数太多的话,提线不了类的封装性。
function sayName(){
console.log(this.name);
}
function Person(name,age,gender){
this.name = name;
this.age = age;
this.gender = gender;
this.sayName = sayname;
}
5.3原型模式
function Person(){};
原型模式的特点:
1.对于共享属性 共享函数使用这种方式创建始非常合适的
2.但是对于引用类型的数据就不太好了
5.4构造函数+原型模式
(一)原型链继承
每个构造函数都有一个原型对象,原型对象中都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。当原型对象等于另外一个类型的实例即继承,调用某个方法或者属性的步骤。
- a.搜索实例
- b.搜索原型
- c.搜索父类原型
//定义父类类型
function Animal(){
this.name = "animal"
}
Animal.prototype = {
sayName : function(){
alert(this.name);
}
}
//定义子类类型
function Dog(){
this.color = "灰色"
}
//通过将子对象的原型对象指向父对象的一个实例来完成继承
Dog.prototype = new Animal();
//子对象的方法其实是定义在了符类对象的实例上。
Dog.prototype.sayColor = function(){
alert(this.color);
}
var dog = new Dog();
console.log(dog);
dog.sayColor();
dog.sayName();
1.默认原型
所有函数默认原型都是Object的实例,默认原型中都会包含一个内部指针,指向Object.prototype
2.确定原型和实例的关系
1) 通过使用instanceof
instance instanceof Object //true
instance instanceof SuperType //true
instance instanceof SubType //true
2) 通过使用isPrototypeOf()
只要是原型链中出现过的原型,都可以说是该原型链所派生的实例的原型
Object.prototype.isPrototypeOf(instance) //true
SuperType.prototype.isPrototypeOf(instance) //true
SubType.prototype.isPrototypeOf(instance) //true
3.谨慎定义方法
子类型覆盖超类型中的某个方法,或者是需要添加超类中不存在的方法,都需要将给原型添加方法的代码放在继承之后(即替换原型的语句之后)
4.原型链问题
1)通过原型来实现继承时,原型实际上会变成另一个类型的实例,原来的实例属性也就变成了现在的原型属性
2)在创建子类型的实例时,不能向超类型的构造函数传递参数。
因此实践中很少会单独使用原型链
(二)经典继承
经典继承也叫借用构造函数、也叫伪造对象。不仅可以继承方法,也可以继承属性。也称 “伪造对象” 或 “经典继承”,在子类型构造函数的内部调用超类型构造函数。函数不过是在特定环境中执行代码的对象,因此通过apply(),call()方法可以在(将来)新建对象上执行构造函数,即在子类型对象上执行父类型函数中定义的所有对象初始化的代码,结果每个子类实例中都具有了父类型中的属性以及方法。
function Animal(name){
this.name = name;
this.colors = ["red","gray"];
}
function Dog(name){
//继承了Animal
Animal.call(this,name);
this.color = "gray";
}
Animal.prototype.sayName = function(){
alert(this.name);
}
var dog = new Dog();
dog.colors.push("hhh");
console.log(dog);
var animal = new Animal();
console.log(animal);
//如果将函数定义在构造函数中,函数复用无从谈起
dog.sayName();
//在超类型的原型中定义的方法,对于子类型而言是无法看到的
(三)组合继承
原型链继承+经典继承 继承属性和方法,以及原型中的属性和方法,也称"伪经典继承",将原型链和借用构造函数的技术组合在一起。
原理是:使用原型链实现对原型属性和方法的继承,而通过借用构造函数实现对实例属性的继承。
function Animal(name){
this.name = name;
this.colors = ["red","gray"];
}
function Dog(name){
//继承了Animal(属性)
Animal.call(this,name);
this.color = "gray";
}
Animal.prototype.sayName = function(){
alert(this.name);
}
//继承方法
Dog.prototype = new Animal();
Dog.prototype.constructor = Animal;
var dog = new Dog();
dog.colors.push("hhh");
console.log(dog);
var animal = new Animal();
console.log(animal);
dog.sayName(); //可以调用