web前端面試題(二)

*this系列

*介紹一下原型對象

一句話概括就是每個構造函數都有一個原型對象,原型對象都包含一個指向構造函數的指針,而實例都包含一個指向原型對象的內部指針。如下圖所示

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 

*js中使用使用原型(prototype)定義方法的好處

使用原型對象的好處是可以 讓所有對象實例共享它所包含的屬性和方法。換句話說,不必在構造函數中定義對象實例的信息,而是 可以將這些信息直接添加到原型對象中。但是也會存在問題:包含引用類型值的屬性會被共享。

*介紹下原型鏈(解決的是繼承問題嗎)

假如我們讓原型對象等於另一個類型的實例,那麼就出現了原型鏈

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>

*手寫bind函數

簡易版

<!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

*Javascript常見數組編程題

*webpack常見面試題

*HTTP常見面試題

*關於前後端通信在實際項目中的用法

*Cookie等

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章