Code Monkey home page Code Monkey logo

notes's Introduction

notes

一个前端狗的自我成长之路,目的这种是为了记录学习路上遇到的问题。同时避免面试的时候 keywords 式的回答

flex:1 到底代表什么点击

notes's People

Contributors

leemiaoshun avatar

Stargazers

 avatar

notes's Issues

JavaScript的几种创建对象的方式

其实题目这么来讲的话,你会从什么角度去思考呢?
比如 var bar = {} 这算不算一种方法?但是这个样子声明对象其实是语法糖。

  • 工厂模式
  • 构造函数模式
  • 原型模式
  • 组合使用构造函数和原型模式
  • 动态原型模式
  • 寄生构造函数模式
  • 稳妥构造函数模式

1. 工厂模式

function Person (name){
    var bar  = new Object();
    bar. a = name;
    bar.say = function(){
        console.log(this.name);
    }
    return bar
}

var person = new Person('jser');

缺点所有对象原型指向一个原型 无法识别对象

2.构造函数模式

  funciton Person(name){
    this.name =  name;
    this.sayName = funciton(){
      console.log(this.name);
    }
    // 没有显示创建对象 
    // 没有return
  }
  var person = new Person('jser');

缺点每次创建实例的时候,方法都会被创造一遍 *
优点实例可以被识别为一个特别模型

3.原型模式

function Person (){}
Perosn.prototype.name = 'jser';
Person.prototype.sayName = function(){
  console.log(this.name);
}
var person = new Person()

方法不会被重复创建

但是不能初始化参数,并且方法会被所有实例共享

4.组合原型模式和构造函数模式

  function Person (name){
    this.name = name;
  }
  Person.prototype.sayName = function(){
    console.log(this.name);
  }
  var person = new Person();

取了二者的优点,方法不会被多次重新创建,并且可以传参数。方法被所有实例共享。该共有共有,该私有私有

5.寄生构造函数模式

function Person(name){
  var bar = new Object();
  bar.name = name;
  bar.sayName = function(){
    console.log(this.name)
  }
  return bar;
}
var person = new Person('jser');

其实跟工厂模式差不多。
无法使用contractor或instanceof识别对象实例的类型。因为都来自 object

6.稳妥构造函数模式

function Person(name){
  var obj = new Object();
  bar.name = name;
  bar.sayName = function(){
    console.log(this.name)
  }
  return obj;
}

新创建的实例不引用 this 不使用 new 操作符创建实例

将变量私有化

同样无法使用 contractor 和 instanceof 识别对象实例的类型,

函数柯里化

讲解同样需要从一个问题开始

add(1)(2)(3)() // 输出6 
// 请完善 add 函数

function add(i) {
  const result = 0;
  const resultList = []
  resultList.push(i)

  const fn = (...args) => {
    if(args.length===0) {
        return resultList.reduce((prev,next)=>{
            return prev + next
        },0)
    }
    resultList.push(args[0])
    return fn
  }
  return fn
}
console.log(add(1)(2)(3)())

JavaScript的几种继承方式

先说答案,再来详细解释

  1. 原型链继承
  2. 借助构造函数继承(经典继承)
  3. 组合继承 1+2 (最常用 )
  4. 原型式继承
  5. 寄生式继承
  6. 继承组合式继承(最理想)

原型链继承

function Parent(){
    this.name = 'jser';
    this.color = ['1','2'];
}
Parent.prototype.sayName = function () {
    console.log(this.name);
}
function Child() {
    this.subName = 'jserrrrrrr'
}
// 核心代码 改写子函数的原型链
Child.prototype = new Parent();

const c1 = new Child();
const c2 = new Child();

c1.color.push("new");
c1.sayName();
console.log(c1.color);
console.log(c2.color);

我们可以发现,原型连方式继承,会发生多个实例共享同一个原型,他们会互相影响。

特点

  1. 父级新增在原型的构造函数,子函数都可以访问到
  2. 来自原型对象的所有属性会被子实例共享,
  3. 构建子函数的时候无法向父函数传递参数

借助构造函数继承(经典继承)

function Parent(name){
    this.name = name;
    this.color = ['1','2','3'];
}

Parent.prototype.getName = function(){
    console.log(this.name);
}
function Child(name,age){
    // 核心代码
    Parent.call(this,name);
    this.age = age;
}

const c1 = new Child('jser','12');
const c2 = new Child('jser1','22');
console.log(c1)
console.log(c2)

特点

  1. 避免引用被所有实例共享
  2. 创建实例的时候可以实现给父函数传递参数
  3. 实例不是父函数的实例,是子函数的实例
  4. 只能继承父函数的实例和方法,不能继承来自原型连的方法
  5. 无法实现函数服用,没创建一个函数就需要调用一次父函数方法

组合继承

function Parent(name){
    this.name = name;
    this.color = [1,2,3];
}
Parent.prototype.sayName = function (){
    console.log(this.name);
}

function Child(name,age){
    // 核心代码1
    Parent.call(this,name);
    this.age = age;
}
// 核心代码2
Child.prototype = new Parent();
Child.contructor = Child;  // contructor设置为构造函数本身

const c1 = new Child('jser',1111);
const c2 = new Child('jser2',2222);
c1.sayName();
c2.color.push('123123');
console.log(c1.color)
console.log(c2.color);

特点

  1. 结合了两者的优点能访问父亲的原型连函数
  2. 数据没有共享,子实例是单独的
  3. 并且可以给父函数传参数
  4. 调用了两次父函数,会生成两份实例

原型式继承

借用 object create 方法

var person = {
    name:'jser',
    color:[1,2,3]
}
var p1 = Object.create(person);
var p2 = Object.create(person);

p1.name = 'jser1';
p2.name = 'jser2';
p1.color.push('1213123');
console.log(p1);
console.log(p2);

特点

  1. 借助原有对象创建实例,没有构造函数
  2. 所有属性会被共享

寄生式继承

function Parent(original){
    var clone = Object.create(original);
    clone.sayName = function(){
        console.log(this.name);
    }
    return clone;
}
var p1 = Parent({
    name:'jser',
    color:[1,2,3]
})
var p2 = Parent({
    name:'jser2',
    color:[1,2,3]
})

特点

  1. 每次都会调用一次创建函数

寄生组合式继承

最常用的构造式原型链继承和构造函数的组合方法,这种方式继承会调用两次父函数,第二遍用来改写原型链,有没有办法可以不调用直接改写呢,
比如直接 Child.prototype = Parent.prototype 这样子做的后果就是 可能在修改子函数的原型的时候无意修改到父函数的原型。所以我们不能用这个方法
我们可以借用一个方法
Object。create 实现,具体语法请看这里 我叫链接

function Parent(name){
    this.name = name;
    this.color = [1,2,3];
}
Parent.prototype.sayName = function (){
    console.log(this.name);
}

function Child(name,age){
    // 核心代码1
    Parent.call(this,name);
    this.age = age;
}
// 核心代码2
Child.prototype = Object.create(Parent.prototype);
Child.contructor = Child;  // contructor设置为构造函数本身

const c1 = new Child('jser',1111);
const c2 = new Child('jser2',2222);
c1.sayName();
c2.color.push('123123');
console.log(c1.color)
console.log(c2.color);

特点

  1. 集优点于一身,构造函数和原型式

flex:1 到底代表什么?

故事的开始要从一个题目开始讲起

<div class="container">
    <div class="left"></div>
    <div class="right"></div>
</div>

<style>
  * {
    padding: 0;
    margin: 0;
  }
  .container {
    width: 600px;
    height: 300px;
    display: flex;
  }
  .left {
    flex: 1 2 300px;
    background: red;
  }
  .right {
    flex: 2 1 200px;
    background: blue;
  }
</style>

求上述代码中的 leftright的实际宽度

这段代码在老王发给我的时候我一瞬间就在想,flex 的放大缩小和占比到底是根据如何一个公式算出来的? 那单纯的 flex:1 又代表什么呢?

问题的解决必须从flex的属性开始说起

  • flex-grow 放大因子 grow 指的是放大的意思,扩展的就是当前flex子项目,扩展所用的空间就是剩余的空白面基
    默认值为0,代表不占用剩余的空白面基来扩充自己。
    1. 如果只有一个子项目
      设置为大于1则独占剩余所有的空白,小于1的情况下则根据比例占据剩余空间的空白
    2. 如果存在多个子项目
      如果多个子项目的属性相加小于1的情况下,则按照比例分割空白区域
      如果相加大于一则所有空白被占用,占比就是属性所占比例
      如果所有子项目都是1 则大家平分 如果 121 则第二个占比50%空白区域
  • flex-shrink 缩小因子当空间不足的情况下,当前子元素收缩比例 ,默认值是 1 意思代表这如果空间不足的情况下会进行收缩。如果值为 0 的情况下,则不收缩。
  1. 如果只有一个子项目设置了 flex-shrink
    大于等于1的情况下,则完全收缩,收缩至当前盒子刚好被填充满,如果小于1的情况下,则收缩尺寸不完全,会有一部分溢出
    2.如果多个子项目都设置了 flex-shrink
    如果当前所有子项目设置的值总和小于1则收缩尺寸不完全,每个元素收缩的值都占完全收缩尺寸的flex-shrink比例
    如果总和大于1则收缩完全每个元素收缩尺寸的比例和flex-shrink值的比例一样。
  • flex-basis 占比(其实在写这个 issue 以前一直以为是 flex-basic 对不起我以前所有的面试官,我还以为我唯一记得的就是这个属性)定义子元素默认占比空间是多少 这个没什么好说的,

那么我们说的flex1到底是个什么呢?

其实 flex 是一个缩写
flex属性是flex-grow,flex-shrink和flex-basis的缩写。
语法
flex: none | auto [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
默认值 flex 1 其实是 flex 0 1 auto 的意思

回头来看这个题目

讲清楚了三个属性的意思,那么就很好记算了。
当前空间还有剩余,剩余为 100px 其中 left占比为 三分之一 right 为 三分之二 答案也就出来了

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.