Erin's Blog


  • Home

  • Archives

Python进阶学习笔记

Posted on 2018-01-15 | In 学习笔记
Python 进阶学习笔记
一、模块
    
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

' a test module '

__author__ = 'Michael Liao'

import sys

deftest():
    args = sys.argv
    if len(args)==1:
        print('Hello, world!')
    elif len(args)==2:
        print('Hello, %s!' % args[1])
    else:
        print('Too many arguments!')

if __name__=='__main__':
    test()

第1行和第2行是标准注释,第一行注释可以让这个hello.py文件直接在Unix/Linux/Mac上运行,第二行注释表示.py文件本身使用标准UTF-8编码。
第4行是一个字符串,表示模块的文档注释,任何模块代码的第一个字符串都被视为模块的文档注释
第6行使用__author__变量把作者写进去
以上是Python模块的标准文件模板
当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__,所以判断__name__是否是__main__可以让一个模块通过命令行运行时执行一些额外的代码,最常见的是运行测试。

在模块中通过_前缀来实现private。
类似__xxx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途。
类似_xxx和__xxx这样的函数或变量就是private的,不应该被直接引用。

Python中,安装第三方模块是通过包管理工具pip完成的。
第三方库都会在Python官方的pypi.python.org网站注册。

pip install xxx

二、面向对象编程
(1)类和实例
            
class Student(object):
    def__init__(self, name, score):
        self.name = name
        self.score = score
    
    defprint_score(self):
        print('%s: %s' % (self.name, self.score))

bart = Student()
class后面紧接着是类名,即Student,类名通常是大写开头单词,紧接着是(object),表示该类是从哪个类继承下来的,通常,如果没有合适的继承类,就是用object类,这是所有类都会继承的类。
(2)获取对象信息
使用type()函数可以判断基本的对象类型。
判断一个对象是否是函数可以使用types模块中定义的常量:

>>> import types
>>> deffn():
...     pass
...
>>> type(fn)==types.FunctionType
True
>>> type(abs)==types.BuiltinFunctionType
True
>>> type(lambda x: x)==types.LambdaType
True
>>> type((x for x in range(10)))==types.GeneratorType
True



Python入门学习笔记

Posted on 2018-01-05 | In 学习笔记
Python 入门学习笔记
一、变量和数据类型
  1. 整数,浮点数,字符串,布尔值,空值(None)
    • 布尔值可以用 and, or 和 not 运算
  1. print语句
    • print 字符串可以用”,”连接起来,中间会输出一个空格
    • 可用+拼接字符串,中间不会有空格
  1. 变量
    •  变量名必须是大小写英文、数字和下划线的组合,且不能用数字开头
    • 变量在计算机内存中的表示:当我们写 a = ‘ABC’ 时,Python解释器干了两件事情:1. 在内存中创建了一个 ’ABC’ 的字符串 2. 在内存中创建了一个名为a的变量,并把它指向 ’ABC’
  1. 字符串
    • 字符串既包含’又包含”的时候需要用到转义
  1. raw 字符串与多行字符串
    • 在字符串前加前缀 r 就表示这是一个raw字符串,里面的字符不需要转义
    • 表示多行字符串可用’’’......’’'
  1. Unicode 字符串
    • 在字符串前加前缀 u 来表示一个Unicode字符串
    • 如果中文字符串在 Python 环境下遇到 UnicodeDecodeError,这是因为.py文件保存的格式有问题。可以再第一行添加注释
# -*- coding: utf-8 -*-
                     目的是告诉Python解释器,用UTF-8编码读取源代码。
  1. 整数与浮点数
    • 整数运算结果仍是整数,浮点数运算结果仍然是浮点数,整数和浮点数混合运算的结果是浮点数
  1. 布尔类型
    • True 和 False
    • 0,空字符串’’,和None都是False
二、list 和 tuple
  1. list
    • list是有序集合
    • [1, 2, 3]
    • empty_list = []
    • 按索引访问,越界会报indexError
    • 访问倒数第几可用负几表示索引
    • 添加新元素用append()添加在最后,insert(index, value)添加在任何地方
    • 删除元素用pop()删除最后一个元素,用pop(index)删除任意元素
    • 替换元素直接将索引指向的值赋新的值
  1. tuple
    • tuple创建了就不可以修改
    • (1, 2, 3)
    • 但是tuple中如果有list,可以修改list中的元素,因为tuple只是引用不能修改,可以修改引用指向的值
    • 访问元素和list一样
    • 创建单元素tuple用(1,)在后面跟逗号的方式表示这是一个单元素tuple
三、条件判断和循环
  1. if
    • Python使用缩进规则,具有相同缩进的代码被视为代码块。缩进须严格按照Python的习惯写法:4个空格。
if ... :
    ...
elif ...:
    ...
else:
    ...

  1. for
    • 遍历list或tuple
for name in L:
    ...
  1. while
while ...:
    ...
    if ...:
        break
    if ...:
        continue
四、dict和set类型
  1. dict
    • 存储对应关系的键值对
d = {
    ‘Adam’: 95,
    ‘Lisa’: 85,
    ‘Bart’: 59
}
    • len()函数可以计算任意集合的大小
    • 通过key访问dict的value,只要key存在,dict就返回对应的value。如果key不存在会直接报错。对此有两种解决方法:1. 先判断一下key是否存在(if ‘Paul’ in d:)2. 使用dict的get方法(d.get(‘Paul’))如不存在则返回None
    • dict有三大特点:1. 查找速度快,无论dict有10个元素还是10万个元素,查找速度都一样,但是dict占用内存大,还会浪费很多内容。dict是按key查找,所以key不能重复 2. dict存储的键值对是没有顺序的,所以打印的顺序不一定是创建时的顺序,而且不同机器打印的顺序可能不同。 3. 作为key的元素必须不可变,Python的基本类型如字符串、整数、浮点数都是不可变的,都可以作为key。但是list是可变的,不能作为key。
    • 要往dict里添加新的键值对可以直接用赋值语句添加(d[‘Paul’] = 72),如果key已经存在,赋值会用新的value替换掉原来的value。
    • 遍历dict和遍历list一样都可用for循环遍历
  1. set
    • set的元素没有重复,而且是无序的。
    • 创建set的方式是调用set()并传入一个list,list的元素将作为set的元素。
    • 如果传入包含重复元素的list,set会自动去掉重复的元素。
    • 可用in操作符来判断set中是否包含某元素。(’Bart’ in s)
    • set有三大特点:1. set不存储value,因此判断一个元素是否在set中速度很快 2. set存储的元素和dict的key类似,必须是不变对象 3. set存储的元素也是没有顺序的
    • 添加元素用add()方法,如果添加的元素已经存在于set中,add()不会报错,只是不会加进去了。
    • 删除元素用remove()方法,如果删除的元素不在set中,remove()会报错。
五、函数
  1. 内置函数
    • 从Python官方网站文档里可以查到内置函数的信息(
      http://docs.python.org/2/library/functions.html#abs
      ),或者再交互式命令行通过help(函数名)查看函数的帮助信息。
    • zip()函数可以把两个list变成一个list:
>>> zip([10, 20, 30], ['A', 'B', 'C'])
[(10, 'A'), (20, 'B'), (30, 'C')]
  1. 编写函数
    • 定义一个函数用def语句,依次写出函数名、括号、括号中的参数和冒号,然后在缩进块中编写函数体,函数的返回值用return语句返回。
def my_abs(x):
    if x >= 0:
        return x
   else:
        return -x
    • 如果没有return语句,函数执行完毕后也会返回结果,结果为None。
  1. 返回多值
    • 可用tuple返回多值,在语法上,返回一个tuple可以省略括号,多个变量可以同时接收一个tuple,按位置赋给对应的值。
  1. 递归函数
    • 在函数内部可以调用其他函数,也可以在函数内部调用自身。
    • 使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以递归调用的次数过多会导致栈溢出。
  1. 默认参数
    • 定义函数的时候可以有默认参数,函数的默认参数的作用是简化调用。直接在写参数的时候给参数赋值就好。
  1. 可变参数
    • 如果想让一个函数能接受任意个参数,可以定义一个可变参数。
def fn(*args):
    print args
    • Python解释器会把传入的一组参数组装成一个tuple传递给可变参数,因此在函数内部可以直接把变量args看成一个tuple。
六、切片
  1. 对list进行切片
    • 切片是从list中去几个元素出来
    • 从零开始取可写成L[:3],左闭右开,从零开始取到索引3位置,但不包括索引3.
    • 从某个索引开始,L[1,3]
    • 从头取到尾,L[:]
    • 切片操作还可指定第三个参数,表示每N个取一个。如L[::2]表示每两个元素取出一个来,也就是隔一个取一个。
    • list 和 tuple 的操作完全相同,只是 tuple 的切片结果也是tuple。
    • 也可用倒数索引进行切片
  1. 对字符串切片
    • 字符串切片结果仍是字符串。’ABCDEF’[:3] == ‘ABC’

七、迭代
  1. 迭代list
    • Python的for循环不仅可以用在list或tuple上,还可以作用在其他任何可迭代对象上。
    • 迭代操作就是对于一个集合,无论该集合有序还是无序,用for循环总是可以依次取出集合的每一个元素。
    • Python中,迭代永远是取出元素本身,而非元素的索引。想要在for循环中拿到索引,可以用enumerate()函数。
>>> L = ['Adam', 'Lisa', 'Bart', 'Paul']
>>> for index, name in enumerate(L):
...     print index, '-', name
...
0 - Adam
1 - Lisa
2 - Bart
3 - Paul
    • 实际上,enumerate()函数把 [‘Adam’, ‘Lisa’, ‘Bart’, ‘Paul’] 变成了类似:[(0, ‘Adam’), (1, ‘Lisa), (2, ‘Bart’), (3, ‘Paul’)],因此迭代的每一个元素实际上是一个tuple
  1. 迭代dict
    • for循环可以迭代dict,每次拿到dict的一个key,但如果希望迭代dict对象的value,可以用values()方法,这个方法把dict转换成一个包含所有value的list。
d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
print d.values()
# [85, 95, 59]
for v ind.values():
    print v
# 85
# 95
    • dict还有一个itervalues()方法,用这个方法替代values()方法,迭代效果完全一样。(py3中已取消此方法)
    • 两个方法的不同之处:1. values()方法实际上把一个dict转换成了包含value的list,而intervals()方法不会转换,它会在迭代过程中依次从dict中取出value,所以itervalues()方法比values()方法节省了生成list所需的内存。 2. 打印itervalues()发现它返回一个<dictionary-valueiterator>对象,这说明在Python中,for循环可作用的迭代对象远不止list,tuple,str,unicode,dict等,任何可迭代对象都可以作用于for循环。
    • 在一个for循环中同时迭代key和value可用items()方法。
>>> d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
>>> print d.items()
[('Lisa', 85), ('Adam', 95), ('Bart', 59)]

>>> for key, value in d.items():
...     print key, ':', value
...
Lisa : 85
Adam : 95
Bart : 59


八、列表生成式
  1. 生成列表
    • 循环生成列表可以写成[x * x for x in range(1,11)],来生成1-10每个数的平方的列表
  1. 复杂表达式
    • 使用for循环的迭代还可以迭代dict。
    • 可以通过一个复杂的列表生成式把dict变成一个HTML表格,字符串可以通过%进行格式化,用指定的参数替代%s。字符串的join()方法可以把一个list拼接成一个字符串。
tds = ['<tr><td>%s</td><td>%s</td></tr>' % (name, score) for name, score in d.iteritems()]
print '<table>'
print '<tr><th>Name</th><th>Score</th><tr>'
print '\n'.join(tds)
print '</table>'
  1. 条件过滤
    • 列表生成式的for循环后面还可以加上if判断
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
  1. 多层表达式
    • 在列表生成式中也可以用多层for循环来生成列表。
>>> [m + n for m in 'ABC' for n in '123']
['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']

实用方法整理

Posted on 2017-03-23 | In 工作笔记

压缩照片(通过canvas实现)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
compressImage(imageData, callback) {
var img = new Image();
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
img.onload = function() {
var width = 0;
var height = 0;
var scaleNumber;
scaleNumber = Math.max(img.width, img.height) > MAX_IMAGE_LENGTH ? (MAX_IMAGE_LENGTH / Math.max(img.width, img.height)) : 1; // 如果照片大于要求大小,缩放到要求大小
width = scaleNumber * img.width;
height = scaleNumber * img.height
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, width, height);// 通过画布画上缩小后的图片再导出
callback(canvas.toDataURL('image/jpeg', 0.8));
}
img.src = imageData;
}

// 使用示例
this.compressImage(reader.result, function(imageData) {
let content = imageData.split('base64,')[1];
me.addFile(content, file.name);
});

scrollTop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
scrollTop(el, from = 0, to, duration = 500) {
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = (
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
return window.setTimeout(callback, 1000/60);
}
);
}
const difference = Math.abs(from - to);
const step = Math.ceil(difference / duration * 50);// 根据duration拆分距离

function scroll(start, end, step) {
if (start === end) return;

let d = (start + step > end) ? end : start + step;// 向后滚
if (start > end) {
d = (start - step < end) ? end : start - step;// 向前滚
}

if (el === window) {
window.scrollTo(d, d);
} else {
el.scrollTop = d;
}
window.requestAnimationFrame(() => scroll(d, end, step));// 循环调用,一次滚一个step
}
scroll(from, to, step);
}

正则表达式学习整理

Posted on 2017-03-23 | In 学习笔记

特殊字符

特殊字符 描述
$ 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘\n’ 或 ‘\r’。要匹配 $ 字符本身,请使用 \$。
() 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。
* 匹配前面的子表达式零次或多次。要匹配 字符,请使用 \。
+ 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。
. 匹配除换行符\n之外的任何单字符。要匹配 . ,请使用\ . 。
[ 标记一个中括号表达式的开始。要匹配 [,请使用\ [。
? 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。
\ 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, ‘n’ 匹配字符 ‘n’。’\n’ 匹配换行符。序列 ‘\\’ 匹配 “\”,而 ‘\(‘ 则匹配 “(“。
^ 匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 \^。
{ 标记限定符表达式的开始。要匹配 {,请使用\{。
\ 指明两项之间的一个选择。要匹配 \ ,请使用 \ 。

*、+和?限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个?就可以实现非贪婪或最小匹配

选择

用圆括号将所有选择项括起来,相邻的选择项之间用|分隔。但用圆括号会有一个副作用,是相关的匹配会被缓存,此时可用?:放在第一个选项前来消除这种副作用。

其中?:是非捕获元之一,还有两个非捕获元是?=和?!,这两个还有更多的含义,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。

匹配中文

1
[\u4e00-\u9fa5]

vue2.0升级笔记

Posted on 2017-03-17 | In 工作笔记
  • el的挂载元素不再支持html、body,需改成css选择器元素。如:

    1
    2
    3
    4
    5
    new Vue({
    el: '#app',
    template: '<App/>',
    components: { App }
    })
  • import vue 的时候,vue会import进vue.common.js,需在webpack中配置alia,将vue绑定到vue.js上。

    1
    2
    3
    4
    5
    resolve: {
    alias: {
    'vue': 'vue/dist/vue.js'
    }
    },

Vue 最早会打包生成三个文件,一个是 runtime only 的文件 vue.common.js,一个是 compiler only 的文件 compiler.js,一个是 runtime + compiler 的文件 vue.js。(ref: http://jiongks.name/blog/code-review-for-vue-next/)

  • 迁移过程中,如果还需在1.0版本下开发,注意重新npm install 一下,以免node module 中引用的还是2.0的vue。
  • $refs不是响应的,无法在computed中监听到变化并更新。
  • 现在在组件上使用 v-on 只会监听自定义事件(组件用 $emit 触发的事件)。如果要监听根元素的原生事件,可以使用 .native 修饰符

基于vue的项目总结

Posted on 2017-03-17 | In 工作笔记

近期杂项总结

  • vue是数据驱动的,不要引入zepto,jQuery等的库,尽量使用数据驱动,如果实在要操作DOM,用ref。
  • 复杂的项目用vuex来管理数据。
  • 处理重试逻辑可以写成:

    1
    2
    3
    getProductInfo().catch((msg) => {
    return getProductInfo()
    })
  • 多语言处理:

  • 建立i18n文件夹,在里面放index.js文件和多语言文件。在index.js中处理切换语言逻辑,把相应的文件export出去
  • 变量前加加号可转换成数字
  • vue-router go 方法中第二个参数为replace,当为true时会替换当前url,使当前页不留下历史记录。

整体架构

  • build中放置webpack配置文件。
  • utils中放公共的方法,工具等。
  • vuex中modules放置每个组件需要存储的数据的state、mutations,并写在store中,actions中写着对外暴露的方法,mutation type中可以对mutation的名字做个和变量的对应关系,数据结构放在models里。
  • 和后台接口的交互都放到service中去,其中可以对sendRequest方法进行封装,处理timeout。一些接口共用的头,以及对response共用的处理,可以写在vue-resource的拦截器里面(Vue.http.interceptor)。具体用法如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
       Vue.http.interceptors.push(function(request, next) {

    // modify request
    request.method = 'POST';

    // continue to next interceptor
    next(function(response) {

    // modify response
    response.body = '...';

    });
    });
  • 在main.js里加上对全局错误的拦截监听,防止未被拦截处理的错误影响程序运行。

  • 如果有日志上报机制,需上报的内容有:用户与页面的交互,页面报错,接口报错。
  • 组件间传数据时,如数据结构可能发生较大改动,直接把对象传给子组件,不要拆开传。子组件api的设计要保证其通用性,在组件内不要加特别定制的逻辑。
  • 报错优先级:影响整体页面展示的错误需要有罩层遮住页面并阻止用户继续与页面进行交互,不影响整体功能的报错可忽略不计,也可显示弹框报错,允许用户稍后再试,或自行处理重试逻辑,重试几次后放弃重试。

工作收获总整理

Posted on 2017-03-17 | In 工作笔记

Vue

  • 箭头函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象,所以不要在vue实例属性或毁掉函数中用箭头函数
  • 在vue里如果要操作DOM,用ref。
  • debounce不会延迟input事件,在使用debounce时应用vm.$watch()相应数据变化。
  • 传入vue.extend()中的选项data和el要使用函数。
  • 【NOTE】名字形式为camelCase的prop用作特性时,需要转为kebab-case。
  • Vue事件在冒泡过程中第一次触发回调之后自动停止冒泡,除非回调明确返回true。
  • 【NOTE】对象/数组的默认值应当由一个函数返回。

git

  • git diff 查看修改内容。

  • git log 看历史记录。

  • git reset —hard HEAD^ 回退到上一个版本。也可以把暂存区的修改回退到工作区。

  • git reset —hard 版本号

  • git reflow 查看每一次命令。

  • git reset —hard commit_id

  • git checkout —文件名 把文件在工作区的修改全部撤销。

    情况1:文件自修改后还没有被放到暂存区,撤销修改就回到和版本库一模一样的状态。

    情况2: 文件已经添加到暂存区后,又作了修改,撤销修改就回到添加到暂存区后的状态。

  • git stash list

  • git stash apply 恢复,恢复后stash 内容不删除。用 git stash drop 来删除

  • git stash pop 恢复的同时把stash内容也删了。

  • git merge —no-ff 分支间的关系更清晰,能看出一个分支拉出去后又合并回来,只会提交一个merge的节点。

css

何时用margin:

  • 需要在border外侧添加空白时
  • 空白处不需要背景(色)时
  • 上下相连的两个盒子之间的空白,需要相互抵消时。【注】margin会相互抵消。

何时用padding:

  • 需要在border内侧添加空白时。
  • 空白处需要背景(色)时。
  • 上下相连的两个盒子之间的空白,希望等于两者之和时。

总结

​ margin用来隔开元素与元素之间的间距,padding用来隔开元素与内容的间隔。margin用于布局分开元素使元素与元素互不相干,padding用于元素与内容之间的间隔,让内容与元素之间有一段呼吸距离。

  • margin、padding这类属性的参数顺序:上,右,下,左 / 垂直方向,水平方向 / top,水平方向,bottom

  • border-radius参数顺序:上左,上右,下右,下左 / 上左下右, 上右下左 / 上左,上右下左,下右

  • 单元格没有外边距。默认情况下,边框被表格的border-spacing属性值间隔,也可以通过设置表格的border-collapse属性值为collapse来完全移除间隔。

  • 特指度(specificity):特指度表示一个css选择器表达式的重要程度。

    可以通过一个公式来计算出一个数值,数越大,越重要。

    “I-C-E”计算公式:I:id,C:class,E:element

    即,针对一个css选择器表达式,遇到一个id就往特指度数值中加100,遇到一个class就往特指度数值中加10,遇到一个element就往特指度数值中加1

    【NOTE】!important优先级最高,高于上面的一切,选择器最低,低于一切。

    简版规则:

    1. 包含ID的选择器胜过包含class的选择器,包含class的选择器胜过包含元素的选择器。
    2. 不同选择器的特指度比较时,不区分加载的顺序(相同选择器在层叠时,后加载的覆盖前加载的)。
    3. 设置的样式高于继承的样式,不用考虑特指度。
    
  • 设置absolute会使得inline元素被“块”化。设置absolute会使得元素已有的float失效。多个悬浮元素后来者居上。

  • 通过设置css属性 -webkit-tap-highlight-color: rgba(0, 0, 0, 0);取消掉手机端webkit浏览器 点击按钮或超链接之类的 默认灰色背景色
    设置css属性 -webkit-user-select:none; 控制用户不可选择文字
    区域性 overflow: scroll | auto 滚动时使用原生效果:-webkit-overflow-scrolling: touch (ios8+,Android4.0+)

JavaScript

  • document.write()可用于直接向HTML输出流写内容。但绝不要使用在文档加载之后,这会覆盖该文档

  • 闭包由两部分组成:函数,以及创建该函数的环境。环境由闭包创建时在作用域中的任何局部变量组成。

  • setTimeout: 调用setTimeout函数会在一个时间段过去后在队列中添加一个消息。这个时间段作为函数的第二个参数被传入。如果队列中没有其他消息,消息会被马上处理。但是,如果有其他消息,setTimeout消息必须等待其他消息处理完。因此第二个参数仅仅表示最少的时间而非确切的时间。

  • reusable function patternL

    可以避免new … 的写法

    // a.js

    1
    2
    3
    4
    5
    6
    export function(settings) {
    function render(container) {}
    render.publicFn1 = function() {}
    render.publicFn2 = function() {}
    return render;
    }

    // b.js

    1
    2
    import a from 'a.js'
    var ainstance = a(settings)(elem);
  • 值类型的类型判断用typeof,引用类型的类型判断用instanceof。

  • 执行上下文:

    1. 变量、函数表达式(init:变量声明,默认赋值为undefined)
    2. this(init:赋值)
    3. 函数声明(init:赋值)

    这三种数据的准备情况称之为执行上下文

    如果代码是函数体,在此基础上附加:

    1. 参数
    2. arguments
    3. 自由变量的取值作用域
  • 函数每被调用一次,都会产生一个新的执行上下文环境。

  • 函数在定义的时候(不是调用的时候),就已经确定了函数内部自由变量的作用域。

    在函数中this到底去何值,是在函数真正被调用执行的时候确定的,函数定义的时候确定不了。

  • 构造函数的函数名第一个字母大写。(构造函数就是用来new对象的函数)

  • this

    • 如果函数作为构造函数用,那么其中的this就代表它即将new出来的对象。
    • 如果函数作为对象的一个属性时,并且作为对象的一个属性被调用时,函数中的this指向该对象。【NOTE】如果fn函数不作为obj的一个属性被调用,如fn函数被赋值到了另一个变量中,那么this的值就是window。
    • 当一个函数被call和apply调用时,this的值就取传入的对象的值。
    • 在全局环境下,this永远是window。
    • 普通函数在调用时,其中的this也都是window。
    • 不仅仅是构造函数的prototype,即便是在整个原型链中,this代表的也都是当前对象的值。

    总结:this指向调用该函数的对象。

  • setAttribute()的两个参数,都必须是字符串。即对特性attribute只能赋值字符串,而对属性property就可以赋任何类型的值。

  • appendChild(), insertBefore()是移动element节点

  • 用promise的时候用catch,不要用err hook。这是因为catch可以捕捉到promise中包括hook中的所有异常。

  • 需要做字数限制时,汉字作为非直接输入的字符,在输入时监听keydown事件和input事件都会直接触发判断字数逻辑,会截断正在输入的文字。解决方法是监听compositionend(当直接的文字输入时触发),这样当没选中中文时不会进行字数判断。

    1
    2
    3
    4
    5
    6
    $('#input').on('compositionend', function(e) {
    var len = $(this).val().length;
    if (len > 16) {
    // 提示超过16字
    }
    });

Webpack

  • 模块加载器的顺序需按照基本—>特殊的顺序使用,否则会报错。(从右往左读)

Erin Ma

7 posts
2 categories
4 tags
© 2018 Erin Ma
Powered by Hexo
|
Theme — NexT.Muse v5.1.4