創建物件的三種方式
ES6前 ,物件不是基于類創建的,而是用一種稱為構建函式的特殊函式來定義物件和它們的特征,
- 通過new關鍵字創建物件
- 通過字面量創建物件
- 通過建構式創建物件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>創建物件的三種方式</title>
</head>
<body>
</body>
<script>
//利用new Object創建物件
let obj1 = new Object();
//利用字面量來創建物件
let obj2 = {};
//利用建構式來創建物件
function People(name, age) {
this.name = name;
this.age = age;
this.say = function() {
console.log('Hello Word');
}
}
//利用建構式來創建實體化物件
let people1 = new People('堯子陌', '24');
console.log(people1);
console.log(people1.name);
people1.say();
</script>
</html>

建構式
建構式是一種特殊的函式,主要用來初始化物件.
即為物件成員變數賦初始值,總之把物件中的公共屬性與方法抽取出來,然后封裝到這個函式里面
注意事項
1.建構式用于創建某一類物件,其首字母要大寫,
2.建構式要與new在一起使用才有意義,
new關鍵字
1.在記憶體中創建一個新物件
2.讓this指向這個新物件
3.執行建構式的代碼,給這個新物件添加屬性與方法
4.回傳這個新物件(建構式不需要retern)
靜態成員和實體成員
靜態成員:在建構式本體上添加的成員被稱為靜態成員,只能由建構式呼叫
實體成員:在建構式內部創建的物件成員被稱為實體成員,只能由實體化的物件來訪問,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>靜態成員與實體成員</title>
</head>
<body>
</body>
<script>
//利用建構式來創建物件
function People(name, age) {
this.name = name;
this.age = age;
this.say = function() {
console.log('Hello Word');
}
}
//實體化物件只能通過實體化物件來呼叫
let people1 = new People('堯子陌', '24');
console.log(people1.name);
people1.say();
//在建構式上添加的成員被稱為靜態成員
People.sex = '男';
console.log(People.sex);
</script>
</html>

原型
建構式很好用 但很浪費記憶體
每一個建構式都有一個prototype屬性,指向一個物件,利用prototype屬性可以共享方法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>原型</title>
</head>
<body>
</body>
<script>
function People(name, age) {
// 在建構式內部創建的成員屬于實體化成員,只有實體化物件才能呼叫
this.name = name;
this.age = age;
}
People.prototype.say =function(){
return "hello woord"
}
var People1 = new People('堯子陌', "23");
console.log(People1.say())
var People2 = new People('驚鴻一面','28');
console.log(People2.say());
console.log(People1.say === People2.say);
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>原型</title>
</head>
<body>
</body>
<script>
//利用建構式來創建物件
function People(name, age) {
this.name = name;
this.age = age;
}
// 在原型上定義方法 所有的實體化物件都可以使用此方法
People.prototype.say = function() {
return 'Hello Word'
}
let people1 = new People('堯子陌', '24');
console.log(people1.say());
let people2 = new People('驚鴻', '24');
console.log(people2.say());
console.log(people1.say === people2.say)
</script>
</html>

物件原型
每個物件向都會有一個_proto_屬性,指向建構式中的prototype物件,且與之全等的關系
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>物件原型</title>
</head>
<body>
</body>
<script>
//利用建構式來創建物件
function People(name, age) {
this.name = name;
this.age = age;
}
// 在原型上定義方法 所有的實體化物件都可以使用此方法
People.prototype.say = function() {
return 'Hello Word'
}
let people1 = new People('堯子陌', '24');
console.dir(People)
//指向建構式的原型
console.log(people1.__proto__);
// 建構式的原型等于實體化物件的物件原型
console.log(people1.__proto__ === People.prototype);
</script>
</html>

constructor建構式
constructor:指向的是參考的建構式,可以讓原型物件重新指向建構式,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>constructor建構式</title>
</head>
<body>
</body>
<script>
//利用建構式來創建物件
function People(name, age) {
this.name = name;
this.age = age;
}
// 原型
People.prototype = {
//將原型物件采用物件賦值的情況下 constructor的指向會變 需要重新手動改回來
constructor: People,
say: function() {
return 'Hello'
},
eat: function() {
return 'Banner'
}
}
let people1 = new People('堯子陌', '24');
//指向建構式的原型
console.log(people1.__proto__);
// 建構式的原型等于實體化物件的物件原型
console.log(people1.__proto__ === People.prototype);
console.log(people1.__proto__.constructor);
console.log(People.prototype.constructor);
</script>
</html>

原型物件 實體物件 建構式之間的關系

原型鏈
任何物件都會有_proto_屬性,且在js中萬物皆物件,由_proto_屬性連起來的鏈條便叫做原型鏈,且最終值為null
建構式的原型的_proto_屬性指向Object.prototype
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>constructor建構式</title>
</head>
<body>
</body>
<script>
//利用建構式來創建物件
function People(name, age) {
this.name = name;
this.age = age;
}
// 原型
People.prototype = {
//將原型物件采用物件賦值的情況下 constructor的指向會變 需要重新手動改回來
constructor: People,
say: function() {
return 'Hello'
},
eat: function() {
return 'Banner'
}
}
let people = new People('堯子陌', '24');
console.log(people.__proto__.__proto__ === People.prototype.__proto__); //true
console.log(People.prototype.__proto__ === Object.prototype); //true
console.log(Object.prototype.__proto__); //null
</script>
</html>

js成員的查找機制
-
當我們訪問一個物件的屬性與方法的時候,首先看這個物件自身有沒有屬性與方法,
-
如果沒有就開始通過原型物件中的_proto_屬性繼續查找(Object.prototype)
-
如果還沒有,就以此類推繼續向上查找,直至值為null的時候
簡單而言,就是沿著一條線查找

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>原型鏈成員查找規則</title>
</head>
<body>
</body>
<script>
function Star(uname, age) {
this.uname = name;
this.age = age;
}
Star.prototype.sing = function() {
console.log('會唱歌');
}
Star.prototype.sex = '女';
let YaoZiMo = new Star('堯子陌', '男');
console.log(YaoZiMo.sex);
console.log(Object.prototype.sex);
console.log(YaoZiMo.toString());
Star.prototype.sing();
console.log(Object.prototype.toString());
</script>
</html>

原型物件中的this指向問題
- 建構式中的this指的是實體化的物件,
- 原型中的this指的是實體化物件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>原型鏈成員查找規則</title>
</head>
<body>
</body>
<script>
function Star(uname, age) {
this.uname = uname;
this.age = age;
console.log(this);
}
var that;
Star.prototype.sing = function() {
that = this;
console.log('會唱歌');
}
var YaoZiMo = new Star('堯子陌', '男');
YaoZiMo.sing()
console.log(that === YaoZiMo);
</script>
</html>

擴展內置物件
可以通過原型物件,對原來的內置物件進行擴展自定義的方法,
注意:內置的陣列和字串等內置物件不能給原型物件覆寫;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>擴展原型物件的內置方法</title>
</head>
<body>
</body>
<script>
// 對內置物件擴展自定義的方法
Array.prototype.sum = function() {
var sum = 0;
for (var i = 0; i < this.length; i++) {
sum += this[i]
}
return sum;
}
// 查看擴展的原型內置方法
console.log(Array.prototype);
var arr = [1, 2, 3];
console.log(arr.sum());
var arr2 = new Array(10, 20, 30);
console.log(arr2.sum());
</script>
</html>

call()方法
call()方法可以呼叫函式,并且可以修改this指向,還可以進行傳參,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>call()方法</title>
</head>
<body>
</body>
<script>
function fn(x, y) {
console.log('Hello Word');
console.log(this);
console.log(x + y);
}
var obj = {
name: '堯子陌'
}
// call()方法 不僅可以呼叫函式 而且可改變函式的this值并且傳遞引數
fn.call(obj, 1, 2)
</script>
</html>

繼承
ES6之前并沒有跟我們提供extends繼承,我們可以通過建構式+原型物件模擬實作繼承,被稱為組合繼承
借用建構式繼承父型別屬性
核心原理:通過call()把父型別的this指向子型別的this,可以實作子型別繼承父型別的屬性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>借助建構式來實作繼承</title>
</head>
<body>
</body>
<script>
//父類建構式
function Father(name, age) {
// 此時的this指向子類的實體化物件
console.log(this);
this.name = name;
this.age = age;
}
//子類建構式
function Son(name, age, score) {
//借助call()方法讓父類的this指向子類的實體化物件
Father.call(this, name, age);
this.score = score;
}
var son = new Son('堯子陌', '18', '100');
console.log(son);
</script>
</html>

借用原型物件繼承父類的方法
思路
-
子類的prototype原型 = new 父類
-
因為父類的實體化物件會另外開辟空間,不會影響父類的原型物件,
-
將子類的constructor重新指向子類的建構式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>借助原型物件類實作繼承</title>
</head>
</body>
<script>
//父類建構式
function Father(name, age) {
// 此時的this指向子類的實體化物件
console.log(this);
this.name = name;
this.age = age;
}
Father.prototype.say = function() {
return 'Hello Word'
}
//子類建構式
function Son(name, age, score) {
//借助call()方法讓父類的this指向子類的實體化物件
Father.call(this, name, age);
this.score = score;
}
//子類的原型物件等于父類的的實體化物件
Son.prototype = new Father();
// 子類的建構式原型物件的constructor重新指向子類
Son.prototype.constructor = Son;
var son = new Son('堯子陌', '18', '100');
console.log(son.say());
console.log(son);
</script>
</html>

ES6新增陣列方法
迭代(遍歷)方法:forEach(),map(),filter(),some(),every()
forEach()
array.forEach(function(currentValue,index,arr)
- currentValue:陣列當前項的值
- index:陣列當前項的索引
- arr:陣列物件的本身
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>forEach遍歷陣列</title>
</head>
<body>
</body>
<script>
// 創建一個陣列
let arr = [1, 2, 3];
//求和的變數
var sum = 0;
arr.forEach(function(value, index, array) {
console.log(value);
console.log(index);
console.log(array);
sum += value;
return sum;
})
console.log(sum);
</script>
</html>

filter()
array.filter(funcction(curentValue,index,arr))
注意:主要用來篩選陣列,回傳的是新陣列
- currentValue:陣列當前項的值
- index:陣列當前項的索引
- arr:陣列物件的本身
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>filter()</title>
</head>
<body>
<script>
var arr = [20, 50, 80, 100, 150, 500, 600];
var newArr = arr.filter(function (value, index, array) {
//篩選大于100的陣列元素,回傳一個新陣列
return value > 100;
})
console.log(newArr)
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>filter之篩選陣列</title>
</head>
<body>
</body>
<script>
// 創建一個陣列
let arr = [100, 500, 800];
//求和的變數
var sum = 0;
var newArr = arr.filter(function(value, index, array) {
return value > 100;
})
console.log(newArr);
</script>
</html>

some()
array.some(funcction(curentValue,index,arr))
注意:主要用來查詢陣列,回傳的是布林值,當查找到第一個滿足條件的陣列元素,則停止查找
- currentValue:陣列當前項的值
- index:陣列當前項的索引
- arr:陣列物件的本身
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>some之查詢陣列</title>
</head>
<body>
</body>
<script>
var arr = ['grren', 'red', 'yellow'];
var flag = arr.some(function(value, index, arr) {
return value == 'yellow'
})
console.log(flag);
</script>
</html>

查詢商品案例
核心思路
- 把資料渲染到頁面中(forEach)
- 根據價格渲染資料(filter)
- 根據商品名稱渲染資料
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
table {
width: 400px;
border: 1px solid #000;
border-collapse: collapse;
margin: 0 auto;
}
td,
th {
border: 1px solid #000;
text-align: center;
}
input {
width: 50px;
}
.search {
width: 600px;
margin: 20px auto;
}
</style>
</head>
<body>
<div class="search">
按照價格查詢: <input type="text" class="start"> - <input type="text" class="end"> <button class="search-price">搜索</button> 按照商品名稱查詢: <input type="text" class="product"> <button class="search-pro">查詢</button>
</div>
<table>
<thead>
<tr>
<th>id</th>
<th>產品名稱</th>
<th>價格</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
// 利用新增陣列方法操作資料
var data = [{
id: 1,
pname: '小米',
price: 3999
}, {
id: 2,
pname: 'oppo',
price: 999
}, {
id: 3,
pname: '榮耀',
price: 1299
}, {
id: 4,
pname: '華為',
price: 1999
}, ];
//1.獲取對應的元素
let tbody = document.querySelector('tbody');
let search_price = document.querySelector('.search-price');
let start = document.querySelector('.start');
let end = document.querySelector('.end')
let product = document.querySelector('.product');
let search_pro = document.querySelector('.search-pro')
//2.將資料渲染到頁面中
setDate(data)
function setDate(MyDate) {
tbody.innerHTML = ''
MyDate.forEach(function(value, index, array) {
var tr = document.createElement('tr');
tr.innerHTML = '<td>' + value.id + '</td><td>' + value.pname + '</td><td>' + value.price + '</td>';
tbody.appendChild(tr)
})
}
//2.根據商品查詢價格模塊
search_price.addEventListener('click', function() {
var newDate = data.filter(function(value, index, array) {
return value.price >= start.value && value.price <= end.value
})
// 再次渲染資料
setDate(newDate)
})
//3.查找商品
search_pro.addEventListener('click', function() {
var arr = [];
data.some(function(value, index, array) {
if (value.pname === product.value) {
arr.push(value)
return true
}
})
setDate(arr)
})
</script>
</body>
</html>

forEach() filter() some()的區別
篩選陣列元素的情況下 some()效率更高
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>forEach() filter() some()的區別</title>
</head>
<body>
</body>
<script>
let arr = ['grren', 'yellow', 'red']
// 利用forEach篩選陣列元素
arr.forEach(function(value, index, array) {
if (value == 'yellow') {
console.log('已找到元素');
return true
}
console.log('forEach');
})
// 利用filter篩選元素
arr.filter(function(value, index, array) {
if (value == 'yellow') {
console.log('已找到元素');
return true
}
console.log('filter');
})
// 利用some篩選元素
arr.some(function(value, index, array) {
if (value == 'yellow') {
console.log('已找到元素');
return true
}
console.log('some');
})
</script>
</html>

字串方法
trim()
trim()方法可以去除字串兩側的空白
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>trim()</title>
</head>
<body>
<input type="text">
<button>提交</button>
<div></div>
</body>
<script>
var str = ' andy ';
console.log(str.length);
var str1 = str.trim();
console.log(str1);
console.log(str1.length);
var input = document.querySelector('input');
var bth = document.querySelector('button');
var box = document.querySelector('div');
bth.addEventListener('click', function() {
var str2 = input.value.trim();
if (str2 === '') {
alert('內容為空')
} else {
box.innerHTML = str2
}
})
</script>
</html>

物件方法
Object.keys()
Object.keys():將目標物件的所有屬性保存為陣列
Object.keys(obj)
- 效果類似for…in
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Object.keys()</title>
</head>
<body>
</body>
<script>
// Object.keys():可將目標物件所有的屬性保存為陣列
var obj = {
name: '堯子陌',
age: 24,
sex: '男'
}
console.log(Object.keys(obj));
</script>
</html>

Object.defineProperty()
定義新屬性或修改為原來的屬性 :Object.defineProperty(obj,prop,descriptor)
- obj:必需 目標物件
- prop:必需:定義或修改屬性的名字
- descriptor:必需,目標屬性所必需有的屬性
descriptor說明

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Object.defineProperty()</title>
</head>
<body>
</body>
<script>
var obj = {
id: 'zero',
name: '堯子陌',
age: '25',
}
// 新增屬性
Object.defineProperty(obj, 'sex', {
value: '男'
})
console.log(obj);
Object.defineProperty(obj, 'id', {
//不允許id屬性被修改
writable: false
})
Object.defineProperty(obj, 'address', {
enumerable: false,
writable: false,
configurable: false
})
console.log(Object.keys(obj));
</script>
</html>

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/293748.html
標籤:其他
下一篇:ES6 (二十九)ES6最新提案、do、throw、函式部分執行、管道運算子|>、柯里化、::、Realm API
