*介紹一下原型對象
一句話概括就是每個構造函數都有一個原型對象,原型對象都包含一個指向構造函數的指針,而實例都包含一個指向原型對象的內部指針。如下圖所示
function Person() {
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function () {
alert(this.name);
};
var person1 = new Person();
person1.sayName(); //"Nicholas"
var person2 = new Person();
person2.sayName(); //"Nicholas"
alert(person1.sayName == person2.sayName); //true
使用原型對象的好處是可以 讓所有對象實例共享它所包含的屬性和方法。換句話說,不必在構造函數中定義對象實例的信息,而是 可以將這些信息直接添加到原型對象中。但是也會存在問題:包含引用類型值的屬性會被共享。
*介紹下原型鏈(解決的是繼承問題嗎)
假如我們讓原型對象等於另一個類型的實例,那麼就出現了原型鏈
function SuperType() {
this.property = true;
}
SuperType.prototype.getSuperValue = function() {
return this.property;
};
function SubType() {
this.subproperty = false;
}
//繼承了 SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function() {
return this.subproperty;
};
var instance = new SubType();
alert(instance.getSuperValue()); //true
*ES6中class的原型鏈
class A {
}
class B extends A {
}
B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true
*css水平居中
子元素定寬margin法。滿足以下三個條件margin:0 auto
1.子元素定寬
2.子元素爲塊級元素(行內元素設置爲display:block也算)
3.子元素的margin-left和margin-right都必須爲auto
*css垂直居中
子元素不定高或者定高定位法。水平居中:定位法
1.子元素不定高或者不定高
2.子元素爲絕對定位,並設置top:50%
3.子元素添加transform: translate(0,-50%);
*css水平垂直居中
1.父元素上設置display:flex
2.子元素元素上設置margin:auto。
*經典佈局(左右)(固定+自適應)
父級:display: flex
left: flex: 0 0 200px(固定200px,不放大也不縮小)
right: flex: 1(會隨父級變化)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 參考阮一峯裏面的百分比佈局,要實現和上面一樣的效果(一側固定,一側隨父級進行變化) -->
<!-- flex: 1 =? 1 1 0%
flex: auto => 1 1 auto
flex: none => 0 0 auto;
flex-basis優先級 自身設定 > 0%(flex:1按字體的高度) > auto(採用height) -->
<style>
.wrap {
margin: 0 auto;
width: 80%;
display: flex;
}
#left {
flex: 0 0 200px; /* 左側固定200px */
height: 500px;
background: red;
}
#right {
/* 此處解釋下
flex: 1 1 0%
0%表示此處寬度是按照自身內容寬度來,此處自身內容寬度爲0,但是分配剩餘的空間,所以可以自適應變化
*/
flex: 1; /* 隨父級變化 */
height: 500px;
background: burlywood;
}
</style>
</head>
<body>
<div class="wrap">
<aside id="left"></aside>
<section id="right">5555</section>
</div>
</body>
</html>
*經典佈局(雙飛翼佈局)上下定高,中間自適應
vw和vh是相對於視口(viewport,也可以叫做視區、視界或可視範圍)的寬度和高度。1vw等於視口寬度(viewport width)的百分之一,也就是說100vw就是視口的寬度。同理,1vh等於視口高度(viewport height)的百分之一。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.wrap{
margin: 0 auto;
width: 80%;
height: 100vh; //重點
display: flex;
flex-direction: column;
}
#left{
background: #ccffff;
flex: 0 0 100px;
}
#right{
background: #ccffff;
flex: 0 0 100px;
}
#main{
background: #ffcccc;
flex: 1;
}
</style>
</head>
<body>
<div class="wrap">
<aside id="left"></aside>
<section id="main"></section>
<aside id="right"></aside>
</div>
</body>
</html>
簡易版
<!DOCTYPE <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
</style>
<script>
Function.prototype.customeBind = function(thisArg,...list){
let self = this; // 目標函數
console.log(this); //指向func
return function(...arg2){
self.apply(thisArg,[...list,...arg2])
}
}
function func(...arg){
console.log(this);//this已經改變,指向{a:1}
console.log(arg);//{1,2,3,4,5,6,7,8}
}
// let newFunc = func.bind(1,2,3);
// newFunc(5, 6, 7, 8);
let newFunc2 = func.customeBind({a:1},1,2,3,4);
newFunc2(5,6,7,8);
</Script>
</head>
<body class="Site">
<div class="parent">
</div>
</body>
</html>
構造函數版
<!DOCTYPE <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
</style>
<script>
Function.prototype.customeBind = function(thisArg,...list){
let self = this; // 目標函數
// 自己實現的bind函數,如果把返回的新函數當成了構造函數,此時會遇到問題,
// 就是找不到目標函數原型上的方法
// 解決:讓新函數繼承目標函數的原型
let Bound = function(...arg2){
self.apply(thisArg,[...list,...arg2])
}
// 以某個對象作爲原型創建一個新的對象出來
Bound.prototype = Object.create(self.prototype);
Bound.prototype.custructor = self;
return Bound;
}
function func(...arg){
console.log(this);//this已經改變,指向{a:1}
console.log(arg);//{1,2,3,4,5,6,7,8}
}
func.prototype.miaov = function(){
console.log(this);
}
let newFunc = func.bind({ a: 1 }, 1, 2, 3);
let newFunc2 = func.customeBind({ a: 1 }, 1, 2, 3, 4);
console.log('原生------------------');
let f1 = new newFunc(5, 6, 7, 8);
console.log(f1.miaov);
console.log('自定義-----------------');
let f2 = new newFunc2(5, 6, 7, 8);
console.log(f2.miaov);
console.log('看看f2');
console.log(f2);
</Script>
</head>
<body class="Site">
<div class="parent">
</div>
</body>
</html>
*如何實現繼承
ES5組合繼承(使用原型鏈實現對原型屬性和方法的繼承,通過借用構造函數來實現對實例屬性的繼承。)
function SuperType(name) {
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function () {
alert(this.name);
};
function SubType(name, age) {
//繼承屬性
SuperType.call(this, name);
this.age = age;
}
//繼承方法
SubType.prototype = new SuperType();
/* 每創建一個函數,就會同時創建它的 prototype 對象,
這個對象也會自動獲得 constructor 屬性 */
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function () {
alert(this.age);
};
var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29
var instance2 = new SubType("Greg", 27);
alert(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27
原型式繼承(Object.create())
var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = Object.create(person, {
name: {
value: "Greg"
}
});
console.log(anotherPerson);
alert(anotherPerson.name); //"Greg"
class繼承
直接調用super(name),super是代替的是父類的構造函數,super(name)相當於sup.prototype.constructor.call(this, name)
class sup {
constructor(name) {
this.name = name
}
printName() {
console.log(this.name)
}
}
class sub extends sup{
constructor(name,age) {
super(name) // super代表的事父類的構造函數
this.age = age
}
printAge() {
console.log(this.age)
}
}
let jack = new sub('jack',20)
jack.printName() //輸出 : jack
jack.printAge() //輸出 : 20