创建对象
工厂模式
12345678910111213function createPerson(name, age, job){var o = new Object();o.name = name;o.age = age;o.job = job;o.say = function(){console.log(this.name + ' is a ' + this.age + ' years old ' + this.job);};return o;}var person1 = createPerson('lily', 32, 'teacher');person1.say(); // "lily is a 32 years old teacher"构造函数模式
1234567891011121314151617181920function Person(name, age, job) {this.name = name;this.age = age;this.job = job;this.say = function(){console.log(this.name + ' is a ' + this.age + ' years old ' + this.job);};}// 当作构造函数调用var person1 = new Person('lily', 32, 'teacher');person1.say(); // "lily is a 32 years old teacher"// 作为普通函数调用(全局作用下调用函数,this指向Global对象,浏览器中就是window)Person('mu', 35, 'doctor');window.say();// 在另一个对象的作用域中调用var o = new Object();Person.call(o, 'chen', 20, 'student');o.say();原型模式
- 新建函数时会创建一个
prototype
属性,该属性指向函数的原型;所有原型对象都会获得一个constructor
属性,该属性包含一个指向prototype
属性所在函数的指针 __proto__
这个链接存在于实例person1
与构造函数的原型对象Person Prototype
之间,而不是存在于实例person1
与构造函数Person
之间- 原型中所有属性是被很多实例共享的
- 新建函数时会创建一个
|
|
- 组合使用构造函数模式和原型模式★★1234567891011121314151617function Person(name, age, job) {this.name = name;this.age = age;this.job = job;this.friends = ["lily", "chen"];}Person.prototype.say = function(){console.log(this.friends);};var person1 = new Person("whiskey", 20, "student");var person2 = new Person("tiny", 10, "dotaer");person2.friends.push("COCO");person1.say(); // ["lily", "chen"]person2.say(); // ["lily", "chen", "COCO"]
继承
原型式继承
1234567891011121314151617181920212223242526272829var person = {name: 'whiskey',friends: ['lily', 'mu'],say: function(){console.log(this.friends);}};var person1 = Object.create(person, {name: {value: 'fancypy'}});// 也可以通过person2.name的方式添加姓名// var person2 = Object.create(person);// person1.name = 'SNK';person1.say(); // ["lily", "mu"]console.log(person1.name); // "fancypy"person1.friends.push('coco');person1.say(); // ["lily", "mu", "coco"]// 对于不支持Object.create()的浏览器,可以使用自定义函数function object(o) {function F() {}F.prototype = o;return new F();}组合继承
12345678910111213141516171819202122232425// 组合继承function Parent(name) {this.name = name;}Parent.prototype.sayName = function() {console.log('hi, ' + this.name);};function Child(name, age) {Parent.call(this, name); // 继承属性this.age = age;}// 继承方法// Child.prototype = new Parent();Child.prototype = Object.create(Parent.prototype); //优于上面的Child.prototype.constructor = Child;// 定义自己的方法Child.prototype.sayAge = function() {console.log('I\'m ' + this.age + ' years old');};var lily = new Child('Lily', 20);console.log(lily.sayName()); // "hi, Lily"console.log(lily.sayAge()); // "I'm 20 years old"var whiskey = new Child('whiskey', 30);console.log(whiskey.sayName()); // "hi, whiskey"console.log(whiskey.sayAge()); // "I'm 30 years old"
事件委托
- 事件委托允许我们不必为某些特定的节点添加事件监听器,而是将事件监听器添加到这些节点的某个父节点上。事件监听器分析冒泡事件,去找到匹配的子节点元素,然后做出相应的事件响应。比较常见的情况是用
ul
元素来处理子元素li
的事件 - 优点
- 减少事件注册,节省内存
- 对于新增的子节点无需重新绑定事件
- 缺点
- 仅限于支持事件冒泡的事件
|
|
|
|
正则表达式
\b
:代表单词的开头或结尾,也就是单词的分界处。只匹配一个位置12/\bis\b/.test('this') // false/\bis\b/.test('that is tom') // true.
:匹配除了换行符\n
以外的任意字符\d
:匹配一位数字\s
:匹配任意空白符,包括空格、制表符、换行符、中文全角空格\w
:匹配字母或者数字或者下划线或汉字^
:匹配字符串的开始$
:匹配字符串的结束\
:字符转义\.
匹配.
本身*
:重复0次或更多次+
:重复1次或更多次?
:重复0次或1次{n}
:重复n次{n,}
:重复n次或更多次{n,m}
:重复n到m次,逗号前后不能有空格[]
:匹配没有预定义的元字符的字符集合12[aeiou]匹配aeiou中任何一个字母[0-9]等价于\d|
:分支条件,从左到右满足条件就不管其他了1"into".match(/in|int/) // 匹配in,不会匹配intg
:执行一个全局匹配,即找到所有匹配,而不是找到第一个之后就停止i
:忽略大小写m
:^
、$
能匹配行结束符\W
:大写W,匹配任意不是字母、数字、下划线、汉字的字符\S
:大写S,匹配任意不是空白符的字符\D
:大写D,匹配任意非数字的字符\B
:大写B,匹配不是单词开头或结束的位置[^aeiou]
:匹配除了aeiou
外的任意字符- 元字符:
(
,[
,{
,^
,$
,|
,)
,?
,*
,+
,.
,]
,}
,匹配本身的时候需要转义 ()
:捕获组,用$1表示第一组捕获(?:)
:表示非捕获组regexp.exp
:执行正则表达式,返回一个数组,数组中的第一项是匹配的整个字符串,之后每一项对应捕获组(匹配+捕获)regexp.test
:测试正则表达式,返回布尔值String.match
:返回包含结果的数组,数组中的第一项是匹配的整个字符串,之后每一项对应捕获组,没有匹配项返回nullString.replace
:搜索+替换String.search
:匹配返回该str首次出现的index,不匹配返回-1