一、数据检测的常用方法
1、iintanceOf 用于检测变量的指定数据类型 2、.hasOwnProperty(属性名(key)) 判断当前属性 是否存在于 构造函数 3、in 判断对象是否具有对应属性 包括原型 Key in 对象 4、isPrototypeOf() 判断对象是否是基于对应构造函数创建
//instanceOf 用于检测变量的指定数据类型
function Student(name,age){
this.name=name
this.age=age
}
Student.prototype.show=function(){
conosole.log(this.name)
}
var s1=new Student("王一",21)
instanceof // 检测s1是否为 Student类型
var result=s1 instanceof Student
console.log(result) //t
//isPrototypeOf 判断对象是否是基于对应构造函数创建
isPrototypeOf()
var result=Student.prototype.isPrototypeOf(s1)
console.log(result) //表示s1是基于student的原型创建的
//.hasOwnProperty(属性名(key)) 判断当前属性 是否存在于 构造函数
function Student(name,age){ //创建构造函数student
this.name=name
this.age=age
}
Student.prototype.count=1 //构造函数的原型中有count = 1 这个属性
Student.prototype.show=function(){ //构造函数的原型中有show() 这个属性
conosole.log(this.name)
}
var s1=new Student("王一",21)
console.log(s1.name)
console.log(s1.count)
var r=s1.hasOwnProperty("name")//t
var r1=s1.hasOwnProperty("count")//f 因为count属性存在于函数的原型中
console.log(r)
console.log(r1)
prototype == __proto__ //函数的原型 等于 对象的原型
// in 判断对象是否具有对应属性
function Student(name,age){ //创建构造函数
this.name=name
this.age=age
}
Student.prototype.count=1 //函数原型
Student.prototype.show=function(){
conosole.log(this.name)
}
var s1=new Student("王一",21)
// 对象 key:value
var r= "name" in s1 //name属性 在对象s1的构造函数中
var r1= "count" in s1 //count属性 在对象s1的原型中
var r2= "hello" in s1 //对象s1 中没有 hello 的属性
console.log(r) //t
console.log(r1) //t
console.log(r2) //f
试题
编写一个方法,传入一个对象 以及 key值,判断一下当前这个属性是否是存在于原型中的,如果是返回T,如果不是返回F
function hasPrototype(obj,key){ //key 是否存在于obj的原型中
return key in obj && obj.hasOwnProperty(key)==false
//解释:当key属性在obj中以及不在obj的构造函数函数中则说明在obj的原型中,则返回T否则返回F
}
function Student(name,age){
this.name=name
this.age=age
}
Student.prototype.count=1
Student.prototype.show=function(){
conosole.log(this.name)
}
var s1={
name:"123"
}
var s1=new Student("王一",21)
var r=hasPrototype(s1,"count")
//解释:当count属性在s1中以及不在s1的构造函数函数中则说明在s1的原型中,则返回T否则返回F
console.log(r)
二、面向对象编程的特点
1.抽象性 :通过对象来分析实际问题
2.封装性 :属性和方法 都封装到对象 节约开发成本 维护成本 安全
3.继承性 :java python 举例子讲解
4.多态性 : 一个类 可以创建多种对象 ,js中基本用不着
公开属性:任何的属性都可以直接访问,以及更改 不安全
私有属性:只能通过方法修改不能直接修改,通过制定的方法 访问以及修改,通过获取其中的函数来获取以及设置
function User(name,upass,phone){
var upass=upass
this.name=name
this.phonenumber=phone
//定义两个方法 一个用来访问私有属性 get
this.getUpass=function(){
return upass
}
//一个用来设置私有属性 set
this.setUpass=function(val){
var reg=/\d{11}$/
if(reg.test(val)){
upass=val
}
}
}
//写到原型上也可以
var u1=new User('王一',12346,1523556788)
//u1.name u1.name=
//u1.getName()
//u1.setName()
u1.setUpass(45645645645)
var result=u1.getUpass()
console.log(result)
动物管理系统
继承性:将共有的方法与属性,写到共同的父类中 子类可以直接继承父类的方法或者属性
狗 猫 老虎
分别的创建出 狗类 猫类 老虎类
创建一个动物类,将所有动物的共同的属性和方法,封装到动物类中
不同的类别 继承 动物类的属性和方法
动物 都具有特性
共同的父类
function Animal(name,age,color){ //创建共同的动物类构造函数,共有属性
console.log(this)
this.name=name
this.age=age
this.color=color
}
Animal.prototype.move=function(){
console.log(this.name+'正在动')
}
Animal.prototype.eat=function(){
console.log(this.name+'正在吃')
}
狗类 去继承动物类原型链继承:将Animal创建出来的对象赋值给Dog的原型 将父级的对象赋值给子级的原型
问题 :无法对属性进行初始化 ,所有的属性都是固定
function Dog(name,age,color){
}
Dog.prototype=new Animal("小黑",12,"红色") //将Dog的原型中加入小黑属性
Dog.prototype.watch=function(){
console.log(this.name+"汪汪汪")
}
var d1=new Dog("小白",10,"黑色")
var d2=new Dog('小兰',2,"绿色")
//对象.属性 先去构造函数看一下是否具有该属性,如果没有,再去构造函数原型中去找
//Dog的构造函数为空,所有数据都在其原型中、无法更改原型中的属性值
console.log(d1.name)
console.log(d1)
console.log(d2.name)
猫类 冒充继承:通过 call或者apply来改变this的指向性来完成的继承 可以继承构造函数内容中所有内容
问题:无法继承原型上的内容
初始函数定义的函数中 this指向 所创建出来的环境
this指向某一个对象
function Cat(name,age,color){
Animal.call(this,name,age,color) //将Animal中的this更改指向cat
}
Cat.prototype.maiment=function(){
console.log(this.name+'正在卖萌')
}
var c1=new Cat("小花",2,"蓝色")
console.log(c1) //t 表示 call将Animal中的this指向了cat
c1.eat() //f call 无法将Animal中原型的this改变指向,即无法获取方法原型中的值
console.log(c1)
老虎类
混合继承:通过冒充继承,继承构造函数中的内容,通过原型链继承 继承原型上的内容
function Tiger(name,age,color){
Animal.call(this,name,age,color) //冒充继承 将this指向Tiger
}
Tiger.prototype=new Animal()//原型链继承 move eat
Tiger.prototype.age=21
Tiger.prototype.chiren=function(){
console.log(this.name+"正在吃人")
}
var t1=new Tiger("小胡",2,"白色")
先找Tiget构造函数中是否有对应方法->对应的原型中是否有方法-->Animal的构造函数内部->找到Animal的原型中
t1.eat() //表示继承了Animal构造函数的属性值
console.log(t1.age) //继承了Animal的 原型
三、call 和 apply 的作用
.call(对象,参数,参数) 改变this的指向。第一个参数:更改this指定到的对象。后面的参数就是当前方法需要的参数 .apply(对象,[参数,参数,参数]) 改变this指向 ,还可以改变 传参的方式 , 统一的用数组传参
function Student(name,age){ //创建构造函数
this.name=name
this.age=age
this.showInfo=function(){
console.log(this.name)
}
this.abc=function(a,b,c){ //创建原型
console.log(this.name+a+b+c)
}
}
var s1=new Student("王一",21)
var s2=new Student('王二',22)
s1.showInfo() //原本s1中this指向s1对象
s1.abc(1,2,3)
s1.showInfo.call(s2) //将s1中的this 指向 s2
s1.abc.call(s2,2,3,4)
s1.showInfo.apply(s2) //将s1中的this指向s2
s1.abc.apply(s2,[2,3,4]) //传入方式改变 改为数组传参数
Math.max() //一组数中 最大的数
var max=Math.max(20,50,70,90) //数值中的最大值
console.log(max) //输出最大值
var arr=[20,230,123,124,12] //数组
var max=Math.max(arr) //无法直接对数组进行取最大值
console.log(max) //NaN
var max=Math.max.apply(null,arr) //将数组单独传参
console.log(max)