重學前端之(5)面向對象、new的執行原理

對象

對象的基本概念

什麼是對象??

現實生活中 : 萬物皆對象, 對象是一個具體的事物 , 一個具體的事物就會有 特徵 和 行爲 ;javascript

JavaScript中: js中的對象就是生活中對象的一個抽象,,,, 沒有特徵和行爲,,取而代之的是有對應的屬性和方法 ;java

思考 :數組

1. 學生對象: 
   // 特徵 : 名字,性別,身高,體重
   // 行爲 : 吃飯、睡覺、敲代碼
2.  js的對象 屬性+方法
3. 對象初體驗
var stu = {
      // 鍵 值 對
    // 屬性名 : 屬性值
    // 屬性名 : 變量 => 不是字符型
    // 屬性值 : 任意類型
    name : 'zs',
    gender: '男'
    height:170;
    weight:170;
    eat:function(){
      console.log('吃飯');
    }
}
複製代碼
  • 對象 : 是一組無序的鍵值對的集合bash

  • 特色 :app

    1. 聲明的變量 = {}  []=> 數組
    2. 鍵值對出現
    3. 逗號隔開,, 記住 : 之後再 {} 內一行一行的都是用 , 隔開
    複製代碼

爲何要學習對象?

思考1:若是要存儲一我的的信息,應該怎麼辦?
var name = "張三";
var age = 18;
var sex = "男";
var hobby = "上網";
思考2:這麼作的缺點是什麼?
這些變量都是屬於一我的的,應該跟數組同樣,使用一個集合把全部的信息都存儲起來。
複製代碼

數組:是有序的元素集合 ,數組用於存放一組有序的數據,好比一個班級全部人的名字,一個班級全部人的成績。函數

對象:是一組無序的鍵值對的集合。 對象用於存放一組無序的數據,好比一我的的特徵和行爲。學習

//數組多個元素之間使用,隔開
//對象中多個鍵值對之間也用,隔開,,,鍵值對的格式: 鍵:值
var obj = {
  name:"張三",
  age:18,
  sex:"男",
  hobby:"上網"
}
複製代碼

建立對象-1 (2種方式 單創)

單純的建立一個對象ui

###對象字面量this

字面量 : 直接量,,,經過看數值,,直接看出來類型的 ,或者不須要經過建立, 11, '234', true , [] , {}spa

var p = {};
var p = {
    name : 'zs',
    age:18,
    sayHi:function(){
        console.log(this.name)
    }
}
複製代碼

注意 :

this使用在對象的屬性的函數裏,,其實地方使用沒有意義

經過Object構造函數建立

var p =  new Object(); // 建立一個空的對象
var p =  new Object({name :'xx'});
複製代碼

設置對象的屬性

// 語法 對象名.屬性 = 值
var obj = new Object();
obj.name = 'zs';
obj.age = 18;
obj.gender = '男';

// 添加方法
obj.sayHi = function () {
    console.log('你們好,我是' + obj.name);
}

// 補???
若是存在過的屬性呢???
    
// 設置對象的屬性的語法
    // 對象.屬性 = 值
    // 1. 若是對象有這個屬性,修改這個屬性
    // 2. 若是對象沒有這個屬性,添加這個屬性
複製代碼

獲取對象的屬性

// 語法 對象名.屬性
console.log(obj.name);
console.log(obj.age);
console.log(obj.gender);

//若是是方法,能夠調用
obj.sayHi();


// 獲取對象屬性的語法:
// 對象.屬性:對象的屬性
// 1. 若是有這個屬性,直接返回屬性值
// 2. 若是沒有這個屬性,返回undefined
複製代碼

刪除對象屬性

delete關鍵字能夠刪除對象的屬性

var obj = {name:"zs", age:18}
delete obj.name;//刪除obj的name屬性
複製代碼

##建立對象-2 (2種方式 批量)

批量建立對象

在實際開發中,常常須要建立多個相同類型的對象,好比班級的學生等。

使用工廠函數建立對象

//定義一個函數,用於建立學生對象
  //工廠函數:
  function createStudent(name, age, sex) {
    var stu = {};
    stu.name = name;
    stu.age = age;
    stu.sex = sex;
    stu.sayHi = function() {
      console.log("你們好,我是"+this.name);
    }
    return stu;
  }

  var stu1 = createStudent("zs", 18, "男");
  stu1.sayHi();
複製代碼

優勢:能夠同時建立多個對象

缺點:建立出來的沒有具體的類型,都是object類型的

查看一個對象的類型

typeof 只能判斷基本數據類型的類型
instanceof 判斷對象的具體類型
constructor.name 也能夠獲取到對象的具體類型
複製代碼

關於typeof

  • typeof用於查看基本的數據類型, number string boolean undefined

  • typeof若是查看複雜數據類型,返回的都是object類型。

  • typeof null比較特殊,結果是object

  • typeof 函數的結果是function:由於函數是一等公民

    複製代碼

// 簡單類型

var num1 = 12;

var num2 = 'abc';

var num3 = true;

var num4 = undefined;

var num5 = null;   //(object類型) 
複製代碼

// 複雜類型 (引用類型)

function num6() {

}

var num7 = [];

var num8 = {};

**方式2 : instanceof 判斷**

```js
結構 : 對象 instanceof 構造函數
var arr = [];
var obj = {}
var fn = function () {}
console.log( arr instanceof Array); // true
console.log( obj1 instanceof Object);// true
console.log( fn instanceof Function);// true
複製代碼

方式3 : constructor.name

// 原型的構造函數 
console.log(arr.constructor.name); //Array
console.log(obj1.constructor.name); //Object
console.log(fn.constructor.name); //Function
複製代碼
// 方式1 : typeof
  console.log(typeof num1);
  console.log(typeof num2);
  console.log(typeof num3);
  console.log(typeof num4);
  console.log(typeof num5);
  console.log(typeof num6);
  console.log(typeof num7);
  console.log(typeof num8);


  // typeof 總結 :
  //1. 簡單基本類型 : number string boolean undefined 
  //2. null => object 
  //3. 複雜類型 : object
  //4. 函數 => fuction 一等公民 
複製代碼

自定義構造函數

工廠函數的缺點 就是沒法肯定對象的具體類型

構造函數 ,是一種特殊的函數。主要用來在建立對象時初始化對象, 即爲對象成員變量賦初始值,總與new運算符一塊兒使用在建立對象的語句中。

//全部建立出來的對象都有:
    //name
    //age
    //hobboy
  function Teacher(name, age) {
    //構造函數內部的this指向的是新建立的那個對象
    this.name = name;
    this.age = age;
  }

  var tea = new Teacher("zs", 18);
  console.log(tea);
複製代碼
  1. 構造函數首字母要大寫,要和普通函數做區分(紅寶書)。
  2. 構造函數要和new一塊兒使用纔有意義。
  3. 構造函數的做用是用於實例化一個對象,即給對象添加屬性和方法。

在構造函數內部,this指的是一個新生成的空對象,全部針對this的操做,都會發生在這個空對象上。構造函數之因此叫「構造函數」,就是說這個函數的目的,就是操做一個空對象(即this對象),將其「構造」爲須要的樣子。 若是構造函數內部有return語句,並且return後面跟着一個對象,new命令會返回return語句指定的對象;不然,就會無論return語句,返回this對象

new在執行時的原理

/** *建立一個空對象,做爲將要返回的對象實例 *將這個空對象的原型,指向構造函數的prototype屬性 *將這個空對象賦值給函數內部的this關鍵字 *開始執行構造函數內部的代碼 */
//代碼 演示new的過程
function _new(/* 構造函數 */ constructor, /* 構造函數參數 */ param1) {
  // 將 arguments 對象轉爲數組
  var args = [].slice.call(arguments);
  // 取出構造函數
  var constructor = args.shift();
  // 建立一個空對象,繼承構造函數的 prototype 屬性
  var context = Object.create(constructor.prototype);
  // 執行構造函數
  var result = constructor.apply(context, args);
  // 若是返回結果是對象,就直接返回,不然返回 context 對象
  return (typeof result === 'object' && result != null) ? result : context;
}
 
複製代碼

構造函數的做用(實例化對象): 給建立出來的對象增長屬性和方法。


操做對象的屬性

.語法 ----- 對象名.屬性名 ( 看似變量,不是字符串 )

// 獲取對象屬性的語法:
	// 對象.屬性:對象的屬性
    // 1. 若是有這個屬性,直接返回屬性值
    // 2. 若是沒有這個屬性,返回undefined

// 設置對象的屬性的語法
    // 對象.屬性 = 值
    // 1. 若是對象有這個屬性,修改這個屬性
    // 2. 若是對象沒有這個屬性,添加這個屬性

var obj = {
    name : 'zs'
} 

console.log ( obj.name ) //ok
console.log ( obj.'name' ) // X
obj.name = 'why'; //ok

var key = 'name';

console.log ( obj.key ) // X

複製代碼

[]語法 ---- 對象名 [ 屬性字符串 ] (字符串)

var key = 'name';
console.log ( obj['name'] ) // ok
console.log ( obj[name] ) // X
console.log ( obj[key] ) //ok
複製代碼

兩者的區別:當屬性名是一個字符串存儲在變量中的時候,只能使用關聯數組的方式。

應用場景 : 遍歷對象

遍歷對象

經過for..in語法能夠遍歷一個對象

for (var key in obj) {
    // 鍵
    console.log(key);
    // 值
    console.log(obj[key]);
}
複製代碼
解析
var obj = {};
for (var i = 0; i < 10; i++) {
		obj[i] = i * 2;
}
for(var key in obj) {
	console.log(key + "==" + obj[key]);
}
複製代碼

###判斷一個屬性是不是對象的一個屬性

  • 結構 :

    if (屬性名  in  對象) { .. }
    複製代碼
  • 代碼

var obj = {
	name: 'zs'
}
if ('name' in obj) {
	console.log('是');
}
複製代碼

獲取對象裏的全部屬性

// 結構 : Object.keys(對象)
Object.keys(obj)
複製代碼

值類型與引用類型

JS數據類型

簡單數據類型:number、string、boolean、undefined、null

複雜數據類型:Array、function, Object

簡單數據類型也叫值類型,複雜數據類型也叫引用數據類型,這主要是根據內存存儲方式來區分的。

  • 變量在存儲簡單類型的時候,存的是值自己(值類型)
  • 變量在存儲複雜數據類型的時候,存的是引用,也叫地址(類型)

值類型的存儲

變量存儲數據的時候,存儲的直接就是這個值自己。

demo :
var num = 11;
var num1 = num;
num = 20;
console.log(num);
console.log(num1);
複製代碼

簡單類型進行賦值的時候,賦值的是值自己。

引用類型的存儲

複雜類型: 變量不會存這個對象,對象隨機存在內存中,會有一個地址,變量存儲的僅僅是這個對象的地址。

demo:
var obj = {
  name:"zs",
  age:18
}

var obj1 = obj;
obj1.name = "ls";
console.log(obj.name);
console.log(obj1.name);

////把obj存的地址給了obj1 因此obj和obj1都存放了這個對象的地址,
複製代碼

結論:簡單類型存儲的是值自己,複雜類型存儲的是地址,引入若是把第一個對象賦值給另外一個變量,此時兩個變量會指向同一個對象。

相關文章
相關標籤/搜索