2.面向对象
-
在js中,有2种编程思维
-
面向过程:
-
面向对象:
-
-
核心就是对象(类),对象的组成有2种 {"name":ls, skill:function(){console.log("敲代码")} }
-
属性:描述 静态的
-
方法:行为 动态的
-
-
面向对象三大特点
-
封装
-
继承
-
多态
-
2.1==创建面向对象==
2.1.1字面量创建
==缺点:创建单个==
var obj = { "name": "zs", "age": 23, "skill": function () { console.log("敲代码") } } console.log(obj); console.log(obj.age);//23 obj.skill(); //敲代码 </script>
2.1.2new关键字创建
==缺点:代码冗余==
<script> // 创建张三的对象 // 1.创建空对象 var obj = new Object(); console.log(obj);//{} // 2.添加属性和方法 obj.name = "李四"; obj.age = 20; obj.skill = function(){ console.log("敲代码") } console.log(obj); obj.skill(); </script>
2.1.3工厂模式创建
==缺点:类别识别不明确,代码冗余 浪费内存==
<script> function createObj(name,age){ // name 张三 age 20 //1.创建空对象 var obj = new Object(); //2.添加属性和方法 obj.name = name; obj.age = age; obj.skill = function(){ console.log("敲代码") } // 3.出厂 设置返回值 return obj; } var res1 = createObj("张三",20); console.log(res1); var res2 = createObj("李四",20); console.log(res2); </script>
2.1.4构造函数创建
==缺点:浪费内存==
==如何创建构造函数==
-
构造函数的函数名首字母必须大写,为了和普通函数做区别
-
方法和属性是直接给this
-
必须使用new关键字进行调用 否则和普通函数没有区别
==new操作符做了什么==
-
隐式创建了一个空对象,让this指向这个空对象
-
执行构造函数中的代码
-
将实例化对象的__ proto __ 指向构造函数的prototype
-
隐式返回对象
<script> // 创建构造函数 function Person(name, age) { //new关键字 隐式创建了一个空对象 让this指向这个空对象 //添加属性和方法 必须加给this this.name = name, this.age = age, this.skill = function () { console.log("敲代码") } // new关键字 隐式返回这个对象 } // 实例化对象(调用构造函数) 必须使用new关键字 var res1 = new Person("张三", 20); console.log(res1); var res2 = new Person("李四",10); </script>
2.1.5原型创建
==缺点:不能传参==
//创造构造函数 function Person(){} // 将方法和属性添加到构造函数的prototype上 共享的属性和方法 console.dir(Person); Person.prototype.name = "张三"; Person.prototype.age = 20; Person.prototype.skill = function(){ console.log("敲代码") } console.dir(Person); // 实例化对象 var res1 = new Person(); console.log(res1);//实例化对象的__proto__指向构造函数的prototype console.log(res1.__proto__); var res2 = new Person(); console.log(res2); console.log(res2.__proto__);
2.1.6混合创建
构造函数创建(传参)+原型创建(不传参)
<script> /* name age传参 skill不传参 */ // 创建Student构造函数 function Student(name, age) { this.name = name this.age = age } // 原型创建 prototype Student.prototype.skill = function () { console.log("学习敲代码") } // 实例化对象 var res1 = new Student("张三", 20); console.log(res1); var res2 = new Student("李四", 15); console.log(res2); console.log(res1.name);//张三 res.skill();//学习敲代码 res.skill1();// </script>
2.2==什么是原型和原型链==
-
原型prototype:构造函数中用来存储共享的方法和属性的对象
-
原型属性 __ proto __ :让实例化对象的 proto__指向构造函数的prototype
// Array是js内部创建好的构造函数 console.dir(Array); // 实例化对象 实例化对象的__proto__指向构造函数的prototype var arr = new Array(1,2,3,4,5); console.log(arr); console.log(Array.prototype === arr.__proto__);//true console.dir(Array.prototype);//Array上共享的属性和方法 var arr = new Array(1,2,3,4,5); //arr的__proto__ 指向Array的prototype var arr1 = new Array(4,5,6,6);// arr1的__proto__指向Array的prototype
-
原型链:在创建构造函数和实例化对象的时候 自动形成一种查找关系
先查找自身的属性和方法 然后再找proto,再找构造函数 如果都找不到返回undefined
2.3==this的指向==
1.this的指向问题
-
在事件处理函数中 this指向当前触发事件的对象(标签)
-
在Object数据类型中的方法中 this指向所在方法的对象
-
在普通函数中 this指向window
-
在构造函数中 this指向实例化对象
<script> // 1.在事件处理函数中 this指向当前触发事件的对象(标签) var btn1 = document.getElementById("btn1"); btn1.onclick = function(){ console.log(this);// } // 2.在Object数据类型中的方法中 this指向所在方法的对象 var obj = { "name":"zs", "eat":function(){ console.log(this);//obj } } obj.eat(); // 3.在普通函数中 this指向window function fun1(){ console.log(this);//window } fun1(); // 4.在构造函数中 this指向实例化对象 function Person(name){ this.name = name, this.skill = function(){ console.log(this);//实例化对象 } } var res = new Person("ls"); res.skill(); </script>
2.如何改变this指向
-
call(this的新指向,参数1,参数2......) 参数是分开写的 用逗号分隔
-
apply(this的新指向,[参数1,参数2.....])
var obj = { "name": "小红", "age": 10, "getName": function () { console.log(this.name); } } obj.getName();// 小红 this指向 obj var obj1 = { "name": "小明" } obj.getName.call(obj1);//this指向obj1 小明 function fun1() { console.log(this) } fun1();//this指向window fun1.call(document.documentElement); fun1.call(1);// fun1.call("123");// function fun2(a, b) { console.log(a, b, this); } fun2(100, 200);// 100 200 window fun2.call(obj1, 100, 200);// 100 200 obj1:{name:"小明"} // 详细检测数据类型 console.log(Object.prototype.toString.call("124")) console.log(Object.prototype.toString.call(123)) console.log(Object.prototype.toString.call(true)) console.log(Object.prototype.toString.call(undefined)) console.log(Object.prototype.toString.call(null)) console.log(Object.prototype.toString.call({})) console.log(Object.prototype.toString.call([])) console.log(Object.prototype.toString.call(function () { })) console.log(Object.prototype.toString.call(new Date())) console.log(Object.prototype.toString.call(/\d/gi)) //instanceof 检测当前数据是否属于某个构造函数 function Person() { this.name = "ls" } var res = new Person(); // 检测res是否由Person构造函数创建的 console.log(res instanceof Person);//true
// apply(this的新指向,[参数1,参数2......]) function fun3(a,b){ console.log(this,a,b) } fun3();//window fun3.apply(obj1,[100,200]);// obj1 100 200 //利用Math.max和Math.min求数组中最大的值和最小的值 var arr = [100,80,120,60]; // Math.max(序列1,序列2.....) var a = Math.max.apply("12344",arr); console.log(a); var a = Math.min.apply("123",arr); console.log(a);
3.面向对象的选项卡
<script> // var btn = document.getElementsByTagName("button"); // var odiv = document.getElementsByTagName("div"); // for(var i = 0;i<btn.length;i++){ // btn[i].index =i; // btn[i].onclick = function(){ // for(var j = 0;j<odiv.length;j++){ // odiv[j].style.display = "none"; // } // odiv[this.index].style.display = "block"; // } // } /* 面向对象的选项卡 创建面向对象构造函数 面向对象都是由属性和方法组成的 标签作为对象的属性 点击事件和for循环作为对象的方法 */ function SwitchTab() { // 添加属性 this.btn = document.getElementsByTagName("button"); this.odiv = document.getElementsByTagName("div"); var that = this;// 在这里this还是指向实例化对象的 // 入口方法 添加方法 this.init = function () { for (var i = 0; i < this.btn.length; i++) { this.btn[i].index = i; this.btn[i].onclick = function () { // console.log(this);//在事件处理函数中 this指向当前触发事件的对象 // 如何让this指向实例化对象 that.changeItem(this.index);//想让this指向实例化对象 } } } // 入口方法调用 this.init(); this.changeItem = function (index) { for (var j = 0; j < this.odiv.length; j++) { this.odiv[j].style.display = "none"; } // this.index 想让this指向触发对象 但是现在这个this指向实例化对象 this.odiv[index].style.display = "block"; } } // 实例化对象 new SwitchTab(); </script>