HTTP+JS+CSS(1)

128 阅读4分钟

双飞翼 圣杯布局

<!--圣杯布局-->
<style>
    p {
        margin: 0px;
        padding: 0px;
    }

    #container {
        overflow: hidden;
        padding-left: 200px;
        padding-right: 150px;
    }

    #container p {
        float: left;
    }

    #container .center {
        background-color: red;
        width: 100%;
    }

    #container .left {
        background-color: yellow;
        width: 200px;
        position: relative;
        left: -100%;
        margin-left: -200px;
    }

    #container .right {
        background-color: green;
        width: 150px;
        margin-left: -150px;
        position: relative;
        left: 150px;
    }
</style>

<body>
    <div id="container" class="clearfix">
        <p class="center">我是中间</p>
        <p class="left">我是左边</p>
        <p class="right">我是右边</p>
    </div>
</body>
<!--双飞翼布局-->
<style>
    p {
        margin: 0px;
        padding: 0px;
    }
    
    #container {
        width: 100%;
        float: left;
    }

    #container .center {
        background-color: red;
        margin-left: 200px;
        margin-right: 150px;
    }

    .left {
        background-color: yellow;
        width: 200px;
        margin-left: -100%;
        float: left;
    }

    .right {
        background-color: green;
        width: 150px;
        float: left;
        margin-left: -150px;
    }
</style>

<body>
    <div id="container" class="clearfix">
        <p class="center">我是中间</p>

    </div>
    <p class="left">我是左边</p>
    <p class="right">我是右边</p>
</body>

继承实现常用方式

  1. 构造函数继承
   function abc(name) {
        this.name = name;
        this.fun = function () {
            console.log('zhelishi')
        }
    }

    var newAbc = function () {
        abc.apply(this, arguments);
    }

    var one = new newAbc('lianjie');

    console.log(one.fun())
  1. 原型链继承
function abc(){
}
abc.prototype.name = 'lianjie'

function childs(){
      
}
childs.prototype = new abc()

var child = new childs();
console.log(child.name,'---')  //lianjie ---
  1. 组合继承 原型链+ 构造函数
 function abc(name) {
   this.name = name;
 }
 abc.prototype.fun = function () {
   console.log('fun-abc')
 }

 var ddd = function () {
   abc.call(this, ...arguments)
 }
    
 ddd.prototype = new abc();

 var ccc = new ddd('lianjie');

 console.log(ccc.fun(),'----ccc---')

image.png

可以看到这里是有点问题的,如果子实例去除 name属性,还能访问到父级name,因为abc构造函数执行了两次。

4.原型式继承

同时也是Object.create 原理

function parents(name){
  this.name = name
}

parents.prototype.fun = function(){
  console.log('fun--fun')
}

var todo = function(newO){
  var func = function(){}
    func.prototype = newO;
    return new func()
}

var newChild = new parents() 

var newChild2 = todo(newChild)

console.log(newChild2.fun()) 

5.寄生式

function parents(name){
  this.name = name
}

parents.prototype.fun = function(){
  console.log('fun--fun')
}

var todo = function(newO){
  var func = function(){}
    func.prototype = newO;
    return new func()
}

var newChild = new parents() 

var taoyiceng = function(){
  var newChild2 = todo(newChild)
  newChild2.name = '12323nlk'
  return newChild2
}

var bbb = taoyiceng()

console.log(bbb.name); //12323nlk

6.最终 寄生+组合

var Person = function(age){
        this.age = age
    }

    Person.prototype.add = function(){
        console.log('add')
    }

    function object(obj){
        function F(){}
        F.prototype = obj;
        return new F();
    }

    var obj = object(Person.prototype)  //其实就是复制了父级的prototype 再new了一个实例。

    function Sub(age) {
        Person.call(this); // 这个继承了父类构造函数的属性
        this.age = age;
    } // 解决了组合式两次调用构造函数属性的特点

    Sub.prototype = obj;
    var child = new Sub('12313');
    obj.constructor = Sub;
    console.log(child instanceof Person);  //true
    console.log(child.age,'---') //12313

和组合继承比的好处就是不用new 两次 Person 父级。 在子实例删除父子都有的属性,不会再到父级获取。

11111111.png

怎么判断一个数据的类型

  1. typeof
    //能区分
   console.log(typeof 123); //number
   console.log(typeof '223'); //string
   console.log(typeof function a() { console.log(123123) }); //function
   console.log(typeof 2172141653n);   //bigint
   console.log(typeof Symbol("foo"))  //symbol
   console.log(typeof undefined)  //undefined
   
   //无法区分
   console.log(typeof null)  //object
   console.log(typeof { wew: "12321" });  // object
   console.log(typeof [1, 2, 3, 4, 5])  //object

大部分都能区分,typeof无法区分出来 null 对象 数组 因为都返回 object

  1. instanceOf
   class abc {}
   class exs extends abc{}
   var bbb = new exs()
   console.log(bbb instanceof abc,'---obj--')
   

3.Object.prototype.toString.call

0.1+0.2 !=0.3

进制转换 : js做运算会转换成2进制, 但是最高只能存储53位,采用IEEE 754二进制。53位之后的会被截取掉。

call、apply、bind 实现

  1. call
    var obj = {
        aaa: '123'
    }

    function abc() {
        console.log(obj.aaa, ...arguments)
    }
    abc.call(obj,12312);

call做了三件事 ,第一修改abc的执行环境到obj, 第二执行abc函数。返回 abc函数的返回值

    Function.prototype.myCall = function (context) {
        if (typeof this != 'function') {
            throw new Error('不是函数')
        }

        //不存在为 window对象
        context = context ? context : window;

        //返回执行结果
        var result = null;
        //处理参数
        var args = [...arguments].slice(1);  //还能切数组
        
        context.this = this; //执行方法
        
        result = context.this(...args)

        delete context.this;

        return result;
    }

    var obj = {
        aaa: '123'
    }

    function abc() {
        console.log(obj.aaa, ...arguments,'这里执行---')
        return 2132
    }

    var res = abc.myCall(obj, 12312,123123);
    console.log(res)

结果 11111111.png

  1. apply

仅需把上述args部分改成 args = [...arguments].slice(1)[0];

  1. bind
    var obj = {
        a: "123",
        b: 123123
    }

    Function.prototype.mybind = function (context) {
        const fn = this;

        if (typeof fn != 'function') {
            throw Error('不是函数')
        }

        var argu = [...arguments].slice(1)

        return function Fn() {
            return fn.call(this instanceof Fn ? this : context, argu.concat(...arguments))
        }
    }

    var add = function () {
        console.log(this.a, this.b);
    }

    var newo = add.mybind(obj, '12321')
    var addNewo = new newo();

js 垃圾回收

  1. 标记清除

简单来说就是使用的时候,标记好,当不用的时候,就进行清除策略。在js里要实现一个标记器。 缺点: 定时的进行清除。性能不好。

  1. 引用计数 引用计数就是当var 了一个变量当前标记为0, 当不用了就-1。

更多: juejin.cn/post/698158…

强制缓存

强缓存(Cache-Control: max-age=3153600) 协商缓存

浏览器先通过Cache-Control判断是否过期,max-age,no-cache。如果没过期直接用缓存。过期再判断是否有ETag(相当于唯一标识) ,Last-Modified(最后修改时间,只能精确到秒级)。

注意区别,If-Modified-Since是上次服务器返回头部中的Last-Modified信息。

Last-Modified是由服务器发给浏览器的最后修改时间,If-Modified-Since是浏览器发给服务器的最后修改时间。(互相对应)

服务器拿到If-Modified-Since,和自己服务器资源最后修改时间比较,如果一致,那么就返回304,不一致就返回200。

301和302 304 区别

301和302 浏览器拿到这个状态码都会跳转到新的地址url。

301: 代表永久转移,永久重定向。比如当前网站整个迁移,但是当前域名还用,就通过这个进行转移。

302:临时重定向,之前的网站地址还能用,只不过临时重A跳转到B。

最好用301这里有个坑, 302 很容易造成网址劫持。假如我写了一个页面A,我用302重定向到页面B。很可能

因为某种原因,在搜索引擎上会出现页面A的链接,但是点进去又是页面B。

304: 和缓存有关,如果服务器觉得当前浏览器缓存还能用,就会返回304。