一、检测对象的方法 (以一下对象为例)
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)
----------------------------------------------------------------------------------------------------------------------
1、instanceof 用于检测变量的指定数据类型。
比如:检测一个对象(s1)是否是学生(Student)类型 s1 instanceof Student
2、isPrototypeOf() 判断对象是否是基于对应构造函数创建(几乎与instanceof一样的作用)
3、判断属性的方法
a、.hasOwnProperty(属性名(key)) 判断当前属性 是否存在于构造函数(在原型上的不判断)
比如:检测对象(s1)的构造函数是否包含属性(name) s1.hasOwnProperty("name")
b、in 判断对象是否具有对应属性,key in 对象。(判断范围构造函数以及原型)
比如:可以判断name属性或者count属性书否在对象(s1)上。"name" in s1
"count" in s1 ,结果为真
面试题:编写一个方法,传入一个对象 以及 key值,判断一下当前这个属性是否是存在于原型中的,如果是返回T,如果不是返回F
方法一:
function hasPrototype(obj, key) { //key 是否存在于obj的原型中
if(key in obj){ //判断对象是否具有指定的属性
if(obj.hasOwnProperty(key)){ //判断这个属性是否在 构造函数里
return false
}else{
return true
}
}else{
return false
}
}
方法二:
function hasPrototype(obj, key) { //key 是否存在于obj的原型中
return key in obj && obj.hasOwnProperty(key) == false
} //方法一的缩写,,主要使用 && ,都为真才为真。
二、面向对象的特点
1.抽象性 :通过对象来分析实际问题
面向对象编程:以对象为主作为研究的主要依据,来解决对应业务
把大象装冰箱这么办?
面向过程:每一步怎么做,发现问题,解决问题
1.打开冰箱门
2.把大象装进去
3.把冰箱门关上
面向对象:
1.当前这个案例中需要多少个对象?
2.每一个对象究竟需要哪些属性或者方法?
对象:冰箱
属性:容积
方法:打开门,关上门
对象:大象
属性:体积
方法: 走
2.封装性: 属性和方法 都封装到对象 节约开发成本 维护成本 安全
封装过程中有公有属性和私有属性
公开属性 :任何的属性都可以直接访问,以及更改 不安全
私有属性: 只能通过方法修改不能直接修改,通过制定的方法 访问以及修改
set get 作用以及目的:就是通过方法进行属性的设置(set)以及获取(get),增强安全性
公有属性:
function User(name,upass,phone){
this.upass=upass
this.name=name
this.phonenumber=phone
}
var s1 = new User("万三",“123123”,“xxxxxxxxxx”);
//获取属性
console.log(s1[name]);
//设置属性
s1.name = "李白"
私有属性:
function User(name,upass,phone){
var upass=upass
this.name=name
this.phonenumber=phone
//定义两个方法 一个用来访问私有属性
this.getUpass=function(){
return upass
}
//一个用来设置私有属性
this.setUpass=function(val){
var reg=/\d{11}$/
if(reg.test(val)){
upass=val
}
}
}
3.继承性 :将共有的方法与属性,写到共同的父类中 子类可以直接继承父类的方法或者属性
a、原型链继承:将Animal创建出来的对象 赋值给Dog的原型 将父级的对象 赋值给子级的原型
问题 :无法对属性进行初始化 ,所有的属性都是固定
//人类
function Person(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
}
Person.prototype.eat = function() {
console.log(this.name + "在吃苹果")
}
//教师类
function Teacher(name, age, sex) {
}
Teacher.prototype = new Person("张三", "25", "男")
Teacher.prototype.say = function() {
console.log(this.name + ",上课了")
}
//学生类
function Student(name, age, sex) {
}
Student.prototype = new Person("李四", "15", "男")
Student.prototype.say = function() {
console.log(this.name + ",老师好")
}
var t1 = new Teacher("王五", "25", "女");
var s1 = new Student("赵四", "5", "男");
console.log(t1)
t1.say(); //张三,上课了
s1.say() //李四,老师好
t1.eat() //张三在吃苹果
//优点:可以继承父类的构造函数以及原型上的属性以及方法
//缺点:属性值不能修改,已经固定了。
b、冒充继承:通过 call或者apply来改变this的指向性来完成的继承,可以继承构造函数内容所有内容
问题:无法继承原型上的内容
//人类
function Person(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
}
Person.prototype.eat = function() {
console.log(this.name + "在吃苹果")
}
//教师类
function Teacher(name, age, sex) {
Person.call(this, name, age, sex)
}
Teacher.prototype.say = function() {
console.log(this.name + ",上课了")
}
//学生类
function Student(name, age, sex) {
Person.call(this, name, age, sex)
}
Student.prototype.say = function() {
console.log(this.name + ",老师好")
}
var t1 = new Teacher("王五", "25", "女");
var s1 = new Student("赵四", "5", "男");
console.log(t1)
t1.say(); //王五,上课了
s1.say() //赵四,老师好
t1.eat() //报错:t1.eat is not a function
//优点:可以继承构造函数属性
//缺点:但是不能继承父类原型
c、混合继承:通过冒充继承,继承构造函数中的内容,通过原型链继承 继承原型上的内容
//人类
function Person(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
}
Person.prototype.eat = function() {
console.log(this.name + "在吃苹果")
}
//教师类
function Teacher(name, age, sex) {
//冒充继承
Person.call(this, name, age, sex)
}
//原型继承
Teacher.prototype = new Person("张三", "25", "男")
Teacher.prototype.say = function() {
console.log(this.name + ",上课了")
}
//学生类
function Student(name, age, sex) {
//冒充继承
Person.call(this, name, age, sex)
}
//原型继承
Student.prototype = new Person("李四", "15", "男")
Student.prototype.say = function() {
console.log(this.name + ",老师好")
}
var t1 = new Teacher("王五", "25", "女");
var s1 = new Student("赵四", "5", "男");
console.log(t1)
t1.say(); //王五,上课了
s1.say() //赵四,老师好
t1.eat() //王五在吃苹果
//可以继承构造函数属性,也可以继承父类原型
4.多态性: 一个类 可以创建多种对象 ,js中基本用不着
原型链图
三、更改this指向,call,apply
1、 .call(对象,参数,参数) 改变this的指向
第一个参数:更改this指定到的对象
后面的参数就是当前方法需要的参数
2、 .apply(对象,[参数,参数,参数])
改变this指向 ,还可以改变 传参的方式 , 统一的用数组传参
我们经常使用Math.max()或者Math.min()方法来从一组数据中获取最大或者最小的数
Math.max()语法:Math.max(n1,n2,n3,...,nX),获取里面参数的最大值,不能是数组
var max=Math.max(20,50,70,90)
console.log(max) //90
var arr=[20,230,123,124,12]
var max=Math.max(arr)
console.log(max) //NAN
var max=Math.max.apply(null,arr) //230 可以避免使用循环来比对数字大小