面向对象and正则

1.面向对象

面向过程:POP:分析解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用时再一个一个的依次调用。 Process-oriented programming

面向对象:oop:事物分解成一个个对象,然后由对象之间分工合作 object Oriented Programming

特性:封装性,继承性,多态性

对象:js中一组无序的相关属性和方法的集合,所有事物都是对象

对象由属性和方法组成。

属性:事物的特征,常用名词

方法:事物的行为,常用动词

类:es6新增的,class关键字声明一个类,通过类来实例化对象。

类抽象了对象的公共部分,泛指的某一大类。

1.1 创建类

class Star {
  constructor(uname){
    this.uname = uname;
  }
  sing(song){
    console.log(this.uname + song);
  }
}
var yy = new Star('杨洋');
yy.sing('安心的温柔');

1.2 继承

class Father{
  constructor(x,y){
   this.x = x;
   this.y = y;
  }
  money(){
    console.log('100');
  }
  sum(){
    console.log(this.x + this.y);
  }
}

class Sum extends Father {
  constructor(x,y){
    // 先继承父类,再使用子类的
    super(x,y);// 调用了父类的构造函数
    this.x = x;
    this.y = y;
  }
  subtract(){
    console.log(this.x - this.y);
  }
}
var son new Son(1,2);
son.sum();

注意点:1.es6中没有变量提升,必须先定义再使用

2.类里面的共有的属性和方法一定要加this使用

3.this的指向问题

constructor:this -- 创建的实例对象

方法: this -- 谁调用指向谁

2.构造函数和原型

  • 首字母要大写
  • 使用new关键字创建对象
  • 存在内存的浪费问题
function Star(uname,age){
  this.uname = uname;
  this.age = age;
  this.sing = function (){
    console.log('我会唱歌');
  }
}
var yy = new Star('杨洋');

// 实例成员:构造函数内部通过this添加的成员 只能通过实例化对象访问
//this.uname = uname;
// 不能通过构造函数来访问实例成员
console.log(yy.uname);
// 静态成员:在构造函数本身上添加的成员 
Star.sex = '男';
// 静态函数只能通过构造函数访问
console.log(Star.sex);

构造函数原型prototype:每一个构造函数都有一个prototype这个对象

可以把一些不变的方法直接定义到prototype对象上,对象的实例化方法都可以共享。

function Star(uname,age){
  this.uname = uname;
  this.age = age;
}
// 一般情况下,我们公共的属性定义构造函数里面,公共的方法放到原型上。
/*Star.prototype.sing = function(){
  console.log('我会唱歌');
}*/
Star.prototype = {
  // 指回原来的构造函数
  constructor: Star,
  sing:function(){
    console.log('我会唱歌');
  },
  movie:function(){
    console.log('我会演电影');
  }
}
var yy = new Star('杨洋');

对象原型 proto:构造函数的prototype原型对象,之所以我们对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有proto原型的存在。

因为proto的存在,就会去构造函数的原型上查找,

proto对象原型和原型对象prototype是等价的。

proto和构造函数的原型对象prototype里面都有一个constructor属性-- 指向构造函数本身。

原型链:

  • 只有构造函数,就有proto指向原型对象。
  • 构造函数的原型对象的 proto指向Object的prototype
  • Objec的proto指向 null.

this指向:

  • 构造函数中的this指向 --- 对象实例
  • 构造函数的原型对象中的函数中this指向 --- 对象实例

通过原型对象可以扩展内置对象:

Array.prototype.sum = function(){
  var sum = 0;
  for(var i=0;i<this.length;i++){
    sum += this[i];
  }
  return sum;
}

var arr = [1,2,3];
arr.sum();

1.4 继承

call :可以改变this指向 可以调用函数

// 借用父构造函数继承属性
function Father(uname,age){
  this.uname = uname;
  thi.age = age;
}
// 借用构造函数实现继承不能继承方法
Father.prototype.money = function(){
  console.log('100000');
}
function Son(uname,age,score){
  Father.call(this,uname,age);
  this.score = score;
}

var son = new Son('慕寒',18,100);
console.log(son);
// 借用原型对象继承方法
function Father(uname,age){
  this.uname = uname;
  thi.age = age;
}
// 借用构造函数实现继承不能继承方法
Father.prototype.money = function(){
  console.log('100000');
}
function Son(uname,age,score){
  Father.call(this,uname,age);
  this.score = score;
}
// 修改了父原型对象 -  修改子原型对象 父的也会修改 
// Son.prototype = Father.prototye;

// 如果利用对象的方式修改了原型对象,不忘用constructor指回原来的构造函数
Son.prototype = new Father();
Son.prototype.constructor = Son;
Son.prototype.exam = function(){
  console.log('孩子要考试')
}

var son = new Son('慕寒',18,100);
console.log(son);

1.5 es5新增的方法

数组方法:

//forEach 迭代数组  遍历数组
// map 
var arr = [1,4,5,6];
var sum = 0;
arr.forEach(function(value,index,array){
  console.log('每一个数组元素:',value);
  console.log('每一个数组索引号:',index);
  console.log('数组元素本身:',array);
  sum += value;
});

// filter 筛选数组 返回一个新数组  返回所有满足条件的元素
var arr = [12,55,67];
var newArr = arr.filter(function(value,index,array){
  return value >= 20;
});
console.log(newArr);

// some 返回值是布尔值 查找数组中是否有满足条件的元素存在 如果查找到第一个满足条件的元素就终止循环。
// every
var arr = [13,58,56,60];
var flag = arr.some(function(value,index,array){
  return value > 20;
});
console.log(flag);

字符串方法

// trim 去掉字符串两端的空格 返回一个新的字符串
var str  = '  andy  ';
var str1 = str.trim();

对象方法

// Object.keys(obj); 获取对象自身的所有属性 返回由属性名组成的数组
var obj = {
  id:1,
  pname:'苹果',
  price: 4.55
};
var arr = Object.keys(obj);
console.log(arr); // ["id","pname","price"];

// Object.defineProperty 定义对象的新属性或者修改原来的属性
// 参数:obj, prop[属性],descriptor[描述]

// 添加一条属性 num:1000
Object.defineProperty(obj,'num',{
  value:1000
});

// 修改 价格为5 
Object.defineProperty(obj,'price',{
  value:5
});

// 限定id不能被重写
Object.defineProperty(obj,'id',{
  // 值为false 不允许修改 默认值是false
  writable: false,
  // 是否可以枚举 
  enumrable:false,
  // 是否可以被删除或重新设置
  configurable: false
}) 

3. 函数进阶

函数的定义和调用

  • 函数声明的方式 命名函数

  • 函数表达式 匿名函数

  • new Function 参数是字符串的格式

    // var f = new Function('console.log(123)');
    var f = new Function('a','b','console.log(a+b)');
    f(1,2);
    
  • 所有函数都是Function的实例 函数也是对象

函数的调用方式:

  • 普通函数 函数名() this ---> window
  • 对象的方法 对象.方法(); this ---> 指向调用者
  • 构造函数 new this ---> 指向创建出来的实例
  • 原型对象的this ---> 指向创建出来的实例
  • 绑定事件的函数 触发相应事件调用 this ---> 指向触发事件的对象
  • 定时器函数 定时器每个一定的调用 this ---> window
  • 立即函数 自动调用 (function () {})() this ---> window

改变函数内部的this指向:

  • call: fn.call(this,can1,can2) 继承

  • apply:fn.apply(this,[can1,can2]); 利用apply借助数学内置对象求最大值最小值 数组

    var arr = [1,2,3,4,56,78];
    var max = Math.max.apply(null,arr);
    var min = Math.min.apply(null,arr);
    
  • bind fn.bind(this,can1,can2) 返回原函数的拷贝 不会调用原函数

不需要立即调用,但又需要改变this指向

var o = {
  name: 'andy'
};
function fn(){
  console.log(this);
}
var f = fn.bind(o); 

this

严格模式

(function(){
  // 开启严格模式
  'use strict';
})

// 在严格模式,全局作用域 函数的this指向 undefined
// 严格模式,如果构造函数不加new创建 this指向 undefined
// 定时器中的this --- window
// 事件,对象还是指向调用者

高阶函数

对其他函数进行操作的函数,它接收函数作为参数或将函数作为返回值输出

jquery中动画执行完毕后调用的函数就是 高阶函数

闭包

变量作用域:

闭包:有权访问另一个函数作用域中变量的函数

作用:延伸了变量的作用范围

function fn(){
  var num = 10;
  return function() {
    console.log(num);
  }
}
fn();  // num = 10;

for(var i =0;i<lis.length;i++){
  // 小闭包
  (function (i){
    lis[i].onclick = function(){
      console.log(i);
    }
  })();
}

递归

递归:函数内部自己调用自己

var num = 1;
function fn(){
  console.log('打印6句话');
  if(num == 6){
    return;
  }
  num++;
  fn();
}

// 递归求阶乘
function fn(n){
  if(n == 1){
    return 1;
  }
  return n * fn(n-1);
  
}
fn();

// 斐波那契数列的第n项
// 1 1 2 3 5 8 13 21
function fb(n){
  if(n === 1 || n === 2){
    return 1;
  }
  return fb(n-1) + fb(n-2);
}

// 函数递归完成深拷贝
function deepCopy(newObj,oldObj){
  for(var k in oldObj){
    // 判断属性值是哪种数据类型
    var item = oldObj[k];
    // 是否为数组
    if(item instanceof Array){
      newObj[k] = [];
      deepCopy(newObj[k],item);
    }else if(item instanceof Object){
      //是否为对象
      newObj[k] = {};
      deepCopy(newObj[k],item);
    }else {
       // 简单数据类型
      newObj[k] = item;
    }
  }
}

4.正则表达式

正则表达式:匹配字符串中字符组合的模式 对象形式存在

特点:1.灵活性,逻辑性和功能性非常强

2.可以迅速地用极简单的方式达到字符串的复杂控制

3.对于刚接触的人来说,比较晦涩难懂

// 创建正则表达式
// 利用 RegExp对象
var reg = new RegExp(/123/);
// 字面量
var reg = /123/;

//检测是否符合正则表达式规范
reg.test(123);

元字符:

边界符:

边界符 演示 说明
^ /^abc/ 必须写abc开头
$ /abc$/ 必须以abc结尾
() /(abc){3}/ 让abc重复3次

字符类:

字符流 演示 说明
[] /[abc]/ 只有包含a或者b或者c都返回true
[-] [a-z] 26个大写英文字母任何一个
[-] [^A-Za-z$] 英文字母中任意一个

量词符:设定某个模式出现的次数

量词符 演示 说明
* /^a*$/ 可以出现0次和n次
+ /^a+$/ 可以出现1次和n+1次
/^a?$/ 可以出现0次或1次
{3} /^a{3}$/ 重复3次
{3,} /^a{3,}$/ 重复3次及以上
{3,16} /^a{3,16}$/ 重复3-16次

预定义类:

预定义类 说明
\d 匹配0-9之前的数字 类似[0-9]
\D 匹配所有0-9以外的字符 类似[^0-9]
\w 匹配任意字母数字下划线 [A-Za-z0-9_]
\W 除字母数字下划线以外的字符 [^A-Za-z0-9_]
\s 匹配空格(换行符,制表符,空格符) [\t\r\n\v\f]
\S 匹配非空格字符

正则表达式的替换:replace

var str = 'andyred';
str.replace('andy','bady');
str.replace('/andy/','bady');
// 过滤敏感词
// 只能替换一个
str.replace('/激情/','**');
// g 全局 i 忽略大小写
str.replace('/激情/g','**');

5.es6

ES:EcmaScript 脚本语言的标准化规范

let const

let : 具有块级作用域 --- {} 产生的作用域

可以防止循环变量变成全局变量

不存在变量提升,必须先声明再使用

存在暂时性死区,变量会和块级作用域绑定,不会向上级作用域中查找

let a = 10;
{
  let b = 20;
}
console.log(b); // 访问不到b,报错

const:声明常量 值(内存地址)不能变化的量

具有块级作用域

声明时必须赋初始值,否则会报错

常量赋值后,值不能修改。 -- 基本数据

常量赋值后,不能改变内存地址 --- 复杂数据类型

存储的数据不需要变化,尽量使用const定义变量

const PI = 3.14;
const arr = [100,200];
arr[0] = 'a'; // 可以改
const arr = ['a','b']; // 不能更改,报错

解构赋值

数组解构:一一对应

let [a,b,c] = [1,2,3];
console.log(b);

对象的解构:

let person = {
  name: '慕寒',
  age:30,
  sex: '男'
};
let {name:myName,age,sex} = person;
console.log(myName);

箭头函数

如果函数体中一句代码,可以省略{}

如果形参只有一个,()可以省略

箭头函数不绑定this,没有this,箭头函数定义在哪,this就指向哪

let arr = () = >{
  console.log(123);
}

res = (n1,n2) =>  n1 + n2;

剩余参数

将一个不定量的参数放在一个数组中

const sum = (...args) => {
  let total = 0;
  args.forEach(item => total += item);
  return total;
}

// 匹配结构赋值使用
let arr1 = ['张三','李四','王五'];
let [s1,...s2] = arr1;

扩展运算符

let arr = [1,2,3];
// ...arr;
console.log(...arr);  // 1,2,3
// 用于合并数组
let arr1 = [1,2,3];
let arr2 = [3,4,5];
// 方法1:
let arr3 = [...arr1,...arr2];
// 方法2:
arr1.push(...arr2);

// 可以将伪数组转换为真正的数组
let divs = document.querySeletor('div');
var arr = [...divs];
console.log(arr);
arr.push('a');

// Array.from() 将伪数组转换为真数组
var arr Array.from(divs,item => item * 2);

// find 查找第一个满足条件的值
let arr =  [{
  id:1,
  name: '慕寒'
},{
  id:2,
  name: 'Vk'
}];
let res = arr.find(item => item.id == 2);
console.log(res);

// findIndex 找出第一个符合条件的索引
var arr = [10,20,50];
let res = arr.findIndex(item => item > 15);
console.log(res); // 1

// includes 某个数组是否包含给定的值 返回布尔值
let arr = ['a','b','c'];
arr.includes('a'); // true;
arr.includes('w'); // false

// 模板字符串
// 可以解析变量
// 可以换行
// 可以调用函数 直接显示函数的返回值
let name = '慕寒';
let sayHello = `hello,my name is ${name}`;
console.log(sayHello);
let res = {
  name: '慕寒',
  age: 18
};
let html = `<div>
    <span>${res.name}</span>
    <span>${res.age}</span>
</div>`;

// startsWith endsWith  以什么开头 以什么结尾
let str = 'asrfe';
console.log(str.startWith('as')); // true;
console.log(str.endsWith('fe'));

// repeat 将原字符重复
'x'.repeat(3); // 将x重复3次

Set数据结构

不会存储重复的值,其他和数组一样

const s1 = new Set(['a','b','c']);
console.log(s1.size); // 3
s1.add('d').add('e'); // 添加
s1.delete('a'); // 删除 
s1.has('a'); // 判断某个值是否为s1的成员
s1.clear(); // 清空

// 遍历
s1.forEach(value => {
  console.log(value)
});s
          
// 数组去重
let  s2 = new Set(['a','b','a','c']);
console.log(s2); // 3
let arr = ...s2;
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,165评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,503评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,295评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,589评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,439评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,342评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,749评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,397评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,700评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,740评论 2 313
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,523评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,364评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,755评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,024评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,297评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,721评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,918评论 2 336

推荐阅读更多精彩内容