理解熟练掌握对象
是OOP?
程序中用对象来描述现实中的一个具体事务
什么是对象?
封装了一个事务的属性和功能的程序结构,对象有自己的属性,属性的属性值可以为任意的内容,当属性值为函数的时候,我们称为方法。当属性值为对象的时候,称为子对象
为什么用OOP
和现实中人的想法非常接近,便于大程序的维护
对象用来做什么?
内存中同时存储多个数据和功能的存储空间
什么时候用?
今后开始写程序之前,都要先用对象,描述好要操作东西的属性(静态)和功能(动态),再按照需求使用对象的功能,访问对象的属性
对象的创建形式:
例子
1.对象字面量
var obj = {}; ==>var obj = new Object();
2.系统的构造函数
var obj = new Object();
在js中,万物皆为对象,而对象又拥有自己的属性和方法
例子:
var str = "你好呀!"
//此时str为一个对象,他拥有自己的属性
str.length //为他的属性
str.indexOf("你") //为他的方法
对象不但拥有自己的属性和方法,还可以被定义属性和方法
数据类型
原始 number boolean string undefined null
引用 object array function
不可以改变的原始类型和可以改变的引用类型(地址的改变)
数据的存储,存储是一个地址,不管是原始类型还是引用类型
简而言之:引用数据类型可以直接设置自己的属性和方法(增删改查),而原始数据类型不能直接设置自己的属性和方法,添加上去后又马上删除了
例子:
增
var obj = {};
obj.name = "jack"; //增加属性
console.log(obj.name ) //jack
删 不要轻易使用,很危险!!!
var obj = {};
obj.name = "jack"; //增加属性
delete obj.name;
console.log(obj.name ) //undefined
查
var obj = {};
obj.name = "jack"; //增加属性
console.log(obj.name ) //属性查看
改
var obj = {};
obj.name = "jack"; //增加属性
console.log(obj.name ) //属性查看
obj.name = "铁柱";
console.log(obj.name ) //铁柱
构造(Constructor)方法创建对象
自己定义的构造函数
function Person(){
this.name = "jack";
this.age = "30";
return this;
}
1、构造方法是专门描述一类对象统一结构的函数
2、反复创建多个相同结构的对象时,都要先定义统一的构造函数,再使用构造函数反复创建对象
解决:复用对象的结构代码
构造方法, 就是一个函数,只是说这个函数是用来出对象用的。 遵循大驼峰命名规则(人为定义)
使用new调用构造函数
var p1 = new Person()
当你使用new关键字调用函数以后,数据类型变为object,Person函数里面会产生一个this的空对象,可以理解为将函数体里面的属性和方法放进去
变成这样
function Person(){ //理解版本
var this={
name = "jack",
age = "30",
}
return this;
}
注意:最后返回值为this,如果要强行改变返回值,必须返回的为引用数据类型,原始数据类型不能返回,默认还是返回this
console.log( p1.name) //jack
原始类型是不能添加直接属性和方法的
原始类型的字符串
var str = "hello world";
字符串对象
var str1 = new String("hello world"); //new + 构造函数
console.log(typeof str) //string
console.log(typeof str1) //object
str.abc = "nihao " //可以添加上去,但是马上删除,因为他是原始类型
console.log(str.abc); //undefined
str1.abc = "nihao";
console.log(str1.abc); //nihao
基本包装类型:Boolean,Number,String
var num = 10;
var num1 = new Number(10);
console.log(num,num1) //10 Number {10}
var bol = true;
var bol1 = new Boolean(true);
console.log(bol,bol1) //true Boolean {true}
console.log(typeof num1) // object
关于this指向问题
分为几种情况
1.在函数中使用的this
1.1 正常的预编译(函数的常规调用),this指向的是window
1.2 通过new关键字调用
2.在全局中this指向的是window
this.abc = 123;
console.log(this.abc) //123
3.在对象中,谁调用这个方法,this就指向谁
var name = "222";
var a = {
name : "111",
say : function(){
console.log(this.name);
}
}
a.say(); //111 a调用所以this指向a
var fun = a.say;
fun(); ///222 fun()没有直接被对象调用,默认window.fun(),此时this指向window,在window中找name
var b = {
name : "333",
say : function(fun){
fun(); //fun()没有直接被对象调用,默认window调用,此时this指向window,重点在于被谁调用
}
}
b.say(a.say); //222 fun被调用时并,前面没有直接的对象调用,默认为Windows.fun()
b.say = a.say;
b.say(); //333 被b调用,所以this指向b,去b对象里找name
4.call和apply可以改变this的指向
call/apply
作用:改变this的指向
区别:使用的方法不同,功能是相同的
call用法一:通过改变this指向来查看数据类型
call用法二和apply
例子
注意:这里仅仅只改变this后面追加的属性和方法的指向,并没有改变__proto__的指向
例子2
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
function Student(name,age,sex,tel,gra){
Person.apply(this,[name,age,sex]);//这里的this指向Student函数,通过改变this指向,将Person的参数传递进来
this.tel = tel;
this.gra = gra;
}
var student = new Student('jack',20,'man',123456789,2019);
例子3
<style>
div{
width: 200px;
height: 200px;
border: 1px solid #000;
}
</style>
<script>
var div = document.getElementById("div01");
function fun(){
this.style.background = '#f00';
}
div.onclick = function(){
console.log(this) //函数被div触发调用,所以this指向div,<div id="div01"></div>
fun.call(this) //将this指向改变,可理解为将fun的this给到div的this
console.log(this) //<div id="div01" style="background: rgb(255, 0, 0);"></div>
fun()//函数前面如果没有对象的时候,函数直接执行,都是window去执行的,fun的this指向window,会报错
}
</script>
面试时候的重点
function test(){
}
test() //--> test.call() 这个是本身的面目,只是不需要改变this指向的时候,可以省略