一、预编译样式比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:true,
2.组件的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