前言 在正式開始正文之前,我想你思考幾個問題: 1.什麼是面向對象? 2.面向對象的特性是什麼? 3.面向對象有哪些繼承方式? 好了,看完這三個問題,開始正文的內容吧。 正文 一、面向對象js 面向對象是一個思想,就是把解決問題的註意力集中到對象上,也可以說是通過函數封裝得到的一個類。 面向對象有三 ...
前言
在正式開始正文之前,我想你思考幾個問題:
1.什麼是面向對象?
2.面向對象的特性是什麼?
3.面向對象有哪些繼承方式?
好了,看完這三個問題,開始正文的內容吧。
正文
一、面向對象js
面向對象是一個思想,就是把解決問題的註意力集中到對象上,也可以說是通過函數封裝得到的一個類。
面向對象有三大特點:封裝 繼承 多態
封裝:把所有相關的屬性和方法封裝在一個對象里
繼承:自己沒有的屬性或者方法,把別人的拿過來用
多態:不同的對象根據事件情況,執行代碼不同。
面向對象的繼承方式:
1.原型鏈:首先看當前對象的屬性是不是私有的,是就直接使用,不是的就通過_ _proto_ _往他的類的prototype上查找,有就直接使用,沒有就繼續向上查找,直到查找到基類Object,沒有就是undefined 有就直接使用。這種查找機制叫原型鏈。
原型鏈的作用是節省記憶體空間。
prototype和__proto__的區別:prototype是存儲機制,__proto__是查找機制。
2.模擬繼承 call apply bind
模擬繼承實際上就是執行了一個函數,把this指向改變了當前。 他並沒有節省記憶體空間。
例如:function Fruit(type,color){
this.type=type;
this.color = color;
}
Fruit.prototype = {
use: function () {
console.log("好吃");
}
}
繼續封裝函數
function Apple(type,color,shape){
模擬繼承
Fruit.apply(this,arguments);
就相當於
this.type=type;
this.color = color;
}
var f = new Fruit("水果","yellow");
Apple.prototype = f;
console.dir(f);
var redApp = new Apple("蘋果","紅","circle");
console.dir(redApp)
3.經典繼承
var cat = {
name: "小白",
age: 2,
eat:function(){
console.log("吃老鼠");
}
}
先創建對象
var xh = Object.create(cat);
以cat為原型對象創建的實例 小白
然後修改屬性和方法
xh.name = "小黑";
創建對象的同時就把需要修改的值傳入
var duolaBmeng = Object.create(cat,{
name:{value:"哆啦B夢"},
eat :{value:function(){
console.log("吃銅鑼燒");
}}
});
4.混入式繼承
function extend(obj1,obj2){
for(var k in obj2){
把所有的obj2對應的值賦值給obj1
obj1[k] = obj2[k];
}
}
5.給內置對象(構造函數)擴展方法
if(!Object.prototype.extend){
Object.prototype.extend = function(obj2){
for(var k in obj2){
this[k] = obj2[k]
}
}
}
但是為了避免衝突 給內置對象(構造函數)擴展方法儘力
所以如果公司團隊內部需要擴展,一定要商量好,避免衝突
二、面向對象PHP
面向對象:是一種程式設計模式 簡稱:oop
1.類 通過關鍵字class來定義類 類名首字母要大寫
2.對象 是類的實例,通過new關鍵字 得到一個實例對象 new classname
3.通過訪問修飾符 給類添加成員
Public 添加的成員是公有的,在類外 類內 子類 都可以去訪問他
Protected 受保護的,只能在類的裡面和子類訪問 類的外面不能訪問
Private 私有的 只能在類的裡面訪問。
如果成員前面沒有加修飾符 預設是public
4.實例對象使用 ->訪問類裡面的成員
對象->屬性的時候 屬性前面不加$符
構造函數 constructor
New 實例對象的本質 其實就是調用對應類的構造函數
$this是類的實例對象
註意:屬性成員結束的時候一定要加分號 方法成員 後面不用加分號
5.析構函數
我們new實例的時候其實是調用構造函數,函數調用的時候會開闢記憶體空間。調用完之後會自動銷毀 銷毀前會自動調用_destruct這個析構方法
6.繼承 extends
子類繼承父類 使用extends 關鍵字 子類繼承父類中的屬性和方法。
子類繼承父類的屬性和方法是有限繼承。
Public 修飾的屬性和方法子類都可以繼承
Protected 修飾的屬性和方法 子類都可以繼承
Private 修飾的屬性子類可以繼承 private修飾的方法子類不可以繼承
7.靜態屬性
使用static關鍵字定義的屬性和方法 直接屬於類,不會進入到對象上去。
類如何訪問靜態屬性 類名::靜態屬性 1. ::範圍解析操作符 2.靜態屬性前面加$
靜態方法中不能使用$this關鍵字。 $this 是實例對象,而對象不能訪問靜態成員。
self關鍵字 指向類本身
類裡面想操作靜態屬性 使用self關鍵字
常量 在類中使用關鍵字 const 定義常量成員。類中訪問常量使用self。對象不能操作常量。
克隆 通過關鍵字 clone 來克隆一個對象
如果不想讓類生成實例對象被克隆 在隱藏函數function__clone() 前面修改訪問修飾符為protected就可以了。
8.Interface
使用關鍵字interface定義介面,介面也是一個類
1.介面中方法必須是公有的
2.介面中方法 必須是空的 不能實現 由去實現介面的類去實現
3.使用implements關鍵字 實現介面 並且要實現介面中的所有方法。
9.抽象類
通過關鍵字abstract 定義的類都是抽象類
只要類中的方法被定義為抽象方法,那麼這個類一定是抽象類 抽象方法必須是空,不能定義他具體的功能實現。
註意 1.抽象類不能被實例化
2.子類去繼承抽象類的時候,一定要去實現抽象類的抽象方法,且和抽象方法的訪問許可權必須一致
3.子類使用關鍵字 extends 去繼承抽象類
抽象方法中的參數問題
1.可選參數 帶有預設值的參數為可選參數
2.子類繼承抽象類,如果抽象類中的抽象方法有參數,子類方法必須也有這個參數可以不同名,子類可以包含抽象方法中不存在的可選參數
3.子類方法中可以有父類抽象方法中沒有的可選參數。
10.final關鍵字
Final關鍵字 放在父類中的方法成員前面,子類無法覆蓋父類的這個方法。
11.表單
前端提交數據 可以通過表單提交
主要有八種提交方式:
Get 通過http中的網路地址
Post 通過http中的請求體 可加密
Options
put
delete
head
connect
trace
對於get提交 php$_GET[]接收 對於post提交 php使用$_POST[]接收。
12.繼承
1.原型繼承 將父類的實例對象賦值給子類的原型 私有的公有的都繼承為公有的
例如:function Person(name){
this.name=name;
}
Person.prototype.fn=function(){
console.log(1);
}
var p1 = new Person("張");
function Son(){
this.age=20;
}
Son.prototype = p1;
var s1 = new Son();
2.call 繼承 call方法是函數或類天生自帶的
將父類私有的繼承為子類私有的
Fn.Call(obj,跟fn的參數匹配); 拿obj取代fn中的this然後調用fn
例如:function fn(){
this.a=123;
console.log(this.a);
}
var obj ={a:56};
fn.call(obj);
3.冒充對象繼承
將父類私有的和公有的都繼承為子類私有的。使用for in
例如:function Son(){
this.age=23;
for(var key in p1){
this[key] = p1[key];
}
}
4.混合繼承
私有的繼承為私有的, 私有的和公有的再次繼承為公有的
Call繼承和原型繼承的結合
例如:function Person(){
this.name = "張三";
}
Person.prototype.fn = function(){
console.log(111)
}
var p1 = new Person;
function Son(){
Person.call(this)
}
Son.prototype = p1;
var s1 = new Son;
5.組合繼承
私有繼承為私有 公有繼承為公有
私有繼承私有 藉助call 公有繼承為公有 不能是原型賦值給原型,因為原型是對象,是複合數據類型,是地址賦值給了前者,導致二者指向同一個原型
例如:function Person(){
this.name = "張三";
}
Person.prototype.fn = function(){
console.log(111)
}
var p1 = new Person;
function Son(){
Person.call(this)
}
Son.prototype = Object.create(Person.prototype);
var s = new Son;
s.__proto__.fn=function(){
console.log(22)
}
s.fn();
6.中間類繼承
function fn(a,b,c){
arguments.__proto__=Array.prototype;
arguments.push(86);
}
fn(18,20,30);
13.call和apply的區別
1.call可以傳多個參數 apply只能傳兩個參數 apply的第二個參數必須是數組
2.call和apply都是修改函數中的this的指向的
3.第一個參數都是對象,用於替換函數中的this的,如果不想替換this寫成null就行