20211115-20211121:less和sass的区别;作用域;回流重绘;this指向;小程序学习

一、预编译样式比css样式更强大,变量、嵌套、运算,混入(Mixin)、继承、颜色处理,函数
less和sass的区别
变量符:sass$,less@
less存在块级作用域,sass是全局作用域
条件语句:sass支持ifelse,for;less不支持
文件引用:Scss引用的外部文件命名必须以_开头,@import “_test1.scss”;;less和普通css一样

二、作用域:
1.注意:所有末定义直接赋值的变量自动声明为拥有全局作用域

 function outFun2() {
      variable = "未定义直接赋值的变量"; // 全局作用域
      var inVariable2 = "内层变量2";
    }
    outFun2();
    console.log(variable); //未定义直接赋值的变量

2.函数作用域的作用:为何 jQuery、Zepto 等库的源码,所有的代码都会放在(function(){…})()中。因为放在里面的所有变量,都不会被外泄和暴露,不会污染到外面,不会对其他的库或者 JS 脚本造成影响。这是函数作用域的一个体现。
3.块级作用域的范围注意:
值得注意的是:块语句(大括号“{}”中间的语句),如 if 和 switch 条件语句或 for 和 while 循环语句,不像函数,它们不会创建一个新的作用域。

for (let i = 0; i < 3; i++) {
      let i = 'abc';
       console.log(i);
    }

上面代码正确运行,输出了 3 次abc。这表明函数内部的变量i与循环变量i不在同一个作用域,有各自单独的作用域。
4.函数作用域
就是所谓的"静态作用域",要到创建这个函数的那个域”。 作用域中取值,这里强调的是“创建”,而不是“调用”,切记切记!!

 var x = 10
    function fn() {
      console.log(x)
    }
    function show(f) {
      var x = 20(function () {
        f() //10,而不是20 
      })()
    } 
    show(fn)

5.作用域与执行上下文
JavaScript属于解释型语言,JavaScript的执行分为:解释和执行两个阶段,这两个阶段所做的事并不一样:
解释阶段:词法分析,语法分析,作用域规则确定(我们需要记住一个函数可以访问在它的调用上下文中定义的变量,这个就是词法作用域)
执行阶段:创建执行上下文,执行函数代码,垃圾回收
执行上下文在运行时确定,随时可能改变;作用域在定义时就确定,并且不会改变。

三、游览器回流重绘
1.回流:
游览器窗口,元素尺寸或位置,元素内容,字体大小,增删元素,激活伪类
2.重绘:
当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。
3.注意:游览器处理回流和重绘的机制
浏览器会维护一个队列,把所有引起回流和重绘的操作放入队列中,如果队列中的任务数量或者时间间隔达到一个阈值的,浏览器就会将队列清空,进行一次批处理,这样可以把多次回流和重绘变成一次。
当你访问以下属性或方法时,浏览器会立刻清空队列
clientWidth、clientHeight、clientTop、clientLeft等等

4.避免
css:
避免使用table布局。
尽可能在DOM树的最末端改变class。
避免设置多层内联样式。
将动画效果应用到position属性为absolute或fixed的元素上。
避免使用CSS表达式(例如:calc())。
JS:
避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性。
避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。
也可以先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘。
避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。

四、this指向
按照箭头函数的this是继承于外层代码库的this就很好理解了。外层代码库我们刚刚分析了,this指向的是window,因此这儿的输出结果是window.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>this 永远指向最后调用它的那个对象”</title>
</head>
<body>
  
  <h1>this 永远指向最后调用它的那个对象”</h1>
  <script>
    //改变 this 的指向我总结有以下几种方法:
    // 使用 ES6 的箭头函数
    // 在函数内部使用 _this = this
    // 使用 apply、call、bind
    // new 实例化一个对象


    // ********注意1:setTimeout对象是window
    var name = "windowsName";
    var a = {
        name : "Cherry",
        func1: function () {
            console.log(this.name)     
        },
        func2: function () {
          // “匿名函数的 this 永远指向 window”
          // 你可以这样想,还是那句话this 永远指向最后调用它的那个对象,
          // 那么我们就来找最后调用匿名函数的对象,这就很尴尬了,因为匿名函数名字啊,
          // 笑哭,所以我们是没有办法被其他对象调用匿名函数的。所以说 匿名函数的 this 永远指向 window。
            setTimeout(  function () {
              // var _this = this;
              // 在函数内部使用 _this = this,
                this.func1() //在不使用箭头函数的情况下,是会报错的,因为最后调用 setTimeout 的对象是 window,但是在 window 中并没有 func1 函数。
            },100);
        }
    };
    a.func2()     // this.func1 is not a function

    // ** 
    var person2 = {
      name: 'Christina',
      sayHi: sayHi
    }
    function sayHi(){
      console.log('Hello,', this.name);
    }
    setTimeout(function(){
        person2.sayHi(); // this指向person2
    },200);
    // **
    
    // ********注意2:bind,call,apply:用了之后函数的this执行就确定下来了,bind传参和call一样,可以多个参数,apply只能通过一个参数[]
    function naem () {
    
      console.log(this.name,this.handle());
      this.name = 'sdf'
      this.handle = function() {
        console.log('naem');
      }
    }
    this.name = 'window'
      this.handle = function() {
        console.log('window');
      }
      let obj = {
        name:"obj",
        handle:function() {
          console.log('obj');
        }
      }
    let fin = naem.bind(obj)
    fin()

    // ** this 永远指向最后调用它的那个对象
    function sayHi(){
      console.log('Hello,', this.name);
    }
    var person = {
      name: 'YvetteLau',
      sayHi: sayHi
    }
    var name = 'Wiliam';
    var Hi = function(fn) {
      fn(); // 但是在执行fn的时候,相当于直接调用了sayHi方法(记住: person.sayHi已经被赋值给fn了,隐式绑定也丢了),没有指定this的值,对应的是默认绑定。
    }
    Hi.call(person, person.sayHi);  // 输出的结果是 Hello, Wiliam. 原因很简单,

    // 解决方案:
    function sayHi(){
        console.log('Hello,', this.name);
    }
    var person = {
        name: 'YvetteLau',
        sayHi: sayHi
    }
    var name = 'Wiliam';
    var Hi = function(fn) {
        fn.call(this);
    }
    Hi.call(person, person.sayHi); // Hello, YvetteLau
    Hi(sayHi);                     // Hello, Wiliam
    // **

    // *******注意3:在 JavaScript 非严格模式(non-strict mode)下, 如果第一个参数的值是 null 或 undefined, 它将使用全局对象替代。


    var number = 5;
    var obj = {
      number: 3,
      fn1: (function () {
        var number; // 闭包
        console.log('匿名函数',this);
        this.number *= 2;
        number = 3;
        return function () {
            var num = this.number; // this 指向
            this.number *= 2;
            console.log(num);
            number *= 3; // 作用域
            console.log(number);
        }
      })()
    }
    var fn1 = obj.fn1;
    fn1.call(null);
    obj.fn1(); // fn1修改对象的number值,相对于修改了obj.number值
    console.log(window.number); // 全局作用域

    // **********注意4:箭头函数this指向外层代码库的this
    var obj = {
        hi: function(){
            console.log(this);
            return ()=>{
                console.log(this);
            }
        },
        sayHi: function(){
            return function() {
                console.log(this);
                return ()=>{
                    console.log(this);
                }
            }
        },
        say: ()=>{
            console.log(this);
        }
    }
    let hi = obj.hi();  //输出obj对象
    hi();               //输出obj对象
    let sayHi = obj.sayHi();
    let fun1 = sayHi(); //输出window
    fun1();             //输出window
    obj.say();          //输出window

    // 解决方案:
    var obj = {
      hi: function(){
          console.log(this);
          return ()=>{
              console.log(this);
          }
      },
      sayHi: function(){
          return function() {
              console.log(this);
              return ()=>{
                  console.log(this);
              }
          }
      },
      say: ()=>{
          console.log(this);
      }
    }
    let sayHi = obj.sayHi();
    let fun1 = sayHi(); //输出window
    fun1();             //输出window

    let fun2 = sayHi.bind(obj)();//输出obj
    fun2();                      //输出obj

  </script>
</body>
</html>

五、小程序学习
1.基础
target和currentTarget的区别,target是点击的哪个节点,currentTarget是当前事件所绑定的节点
小程序事件参数传输用data-info
条件wx:if
block相当于templat
hidden属性相对于vue的v-show

一、小程序合法域名,wxs结合wxml渲染页面结构过滤器,有自己的数据类型,commonjs,
二、上拉加载,onreachrefresh
三、下拉刷新,onpulldownrefresh,关闭下拉刷新,wx.stopPulldownrefresh
四、组件:
1.局部在页面的json引入,usingcomponenents:{组件名:组件路径},全局app.json, 同上;
注意:组件的json要设置,component:true2.组件的js文件,调用的是component,页面的js是page;
3.组件的事件定义到methods中,页面的事件和data同级;
4.样式:app.wxss的样式对组建是无效的,只有class选择器有样式scope作用,其他选择器没有样式隔离的作用;使得外界页面可以控制组件的样式,组建的js文件设置options:{styleIsolation:"apply-shared'},shared组建可以影响页面样式
5.传参数:组建设置properties,与vue不同的是,properties可改
6.obsevers监听器:与vue不同可以,一次监听多个
7.父子组建通信:属性绑定,事件绑定,获取组建实例通过this.selectcomponent()
8.子传父,子组建触发父组建的方法通过this.triggerevent(‘事件名’,)
五、behaviors:类似vue的mixins实现代码共享,
六、promise:小程序都是通过回调实现异步操作,用miniprogram实现promise对象,从而使用promise用法
七、vant-weapp,建议1.3.3
八、mobx:mobx-miniprogram mobx-miniprogram-bindings
九、分包:
一个主包,多个分包
1.主包:一般只包含项目的启动页面或tabbar页面、以及分包都需要用到的一些公共资源
2.分包:只包含和当前分包有关的页面和私有资源
3.限制:整个小程序所有分包大小不超过16m(主包和所有分包),单个分包或主包不能超过2m
4.配置: 
5. 
6.独立分包:用户可以直接打开分包页面或主包页面。配置:independent
7.分包预下载,提高打开分包页面速度。配置preloadrule。限制:一个分/主包预下载大小不能超过2m
十、自定义tabbar
配置https://developers.weixin.qq.com/miniprogram/dev/framework/ability/custom-tabbar.html

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值