(一)概述
1 .两大编程思想
①面向过程POP
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步的实现,使用的时候再一个个调用。面向过程的性能比面向对象要高一些,适合和硬件联系比较紧密的东西,比如单片机。
②面向对象OOP
把事物分解成一个个的对象,然后由对象之间分工与合作。每一个对象都是功能中心,具有明确的分工。面向对象编程具有灵活,代码易复用,容易维护和开发的优点,更适合多人合作的大型软件项目。

2 .面向对象的特性:
①封装性
②继承性
③多态性

(二)对象和类的关系
1 .对象
现实生活中,万物皆对象,对象是一个具体的实物,在JS中,对象是一组无序的,相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。对象是由属性和方法构成的。
属性:事物的特征,在对象中用属性来表示,常用名词。
方法:事物的行为,在对象中用方法来表示,常用动词。
2 .类
在ES6中增加了类的概念,可以使用class关键字声明一个类,之后以这个类来实例化对象。

类抽象了对象的公共部分,它是泛指的某一大类。而对象是特指的某一事物,通过类实例化产生的具体的对象。

(三)创建自定义类
1 .语法:

class name {classBody
}

创建实例:类必须使用new关键字来实例化对象

var 实例名称 = new 类名();

2 .类constructor构造函数
constructor()方法是类的构造函数(默认方法),用于传递参数,返回实例对象,通过new生成实例对象时,自动调用该方法,如果没有显示定义,类内部会自动创建一个constructor()。
constructor()可以接收传递过来的参数,并返回实例对象。

class People {constructor (uname, age) {this.uname = uname;this.age = age;}
}
var rose = new People("rose", 18);

3 .类添加方法

class People {constructor (uname) { this.uname = uname }say (message) { document.write(message + this.name)}
}
var rose = new People("rose");
rose.say("Hello");

(四)继承

1 .extends可以使子类继承父类的一些属性和方法。

class Father {constructor () {}money () {document.write("一个小目标");}
}
class Son extends Father { }
var son = new Son();
son.money();

2 .super()关键字用于访问和调用父类的函数,可以调用父类的构造函数,也可以调用父类的普通函数

// super调用父类构造函数
class Father {constructor(a, b) {this.a = a;this.b = b;}sum() { console.log(this.a + this.b); }
}
class Son extends Father {constructor (a, b) {super(a, b);}
}
var son = new Son(1, 2);
son.sum();
// super调用父类普通函数
class F {log() {return "父类";}
}
class S extends F {log() {console.log("调用" + super.log());}
}
var s = new S();
s.log();

3 .继承父类方法的同时扩列自身方法

class Father {constructor(a, b) {this.a = a;this.b = b;}sum() { console.log(this.a + this.b); }
}
class Son extends Father {constructor (a, b) {// 必须先调用supersuper(a, b);this.a = a;this.b = b;}subtract() { console.log(this.a - this.b); }
}
var son = new Son(1, 2);
son.sum();
son.subtract();

(五) ES6中类的注意点
1 .ES6中是没有变量提升的,所以,必须要先有类,才能通过类来实例化对象。
2 .类里面共有的属性和方法必须使用this。
3 .类里面this的指向,constructor里的this指向的是创建的实例对象,而方法里的this指向方法最终的调用者。

(六)构造函数和原型
概述:
ES6之前没有类的概念,在ES6之前,对象并不是通过类创建的,而是通过构造函数创建的。

1 .构造函数:

构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new一起使用,我们可以将对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。
new在执行时,会做四件事情:
①在内存中创建一个新的空对象
②让this指向这个空对象
③执行构造函数里面的代码,给这个新对象添加属性和方法
④返回这个新对象(所以构造函数里不需要return)

2 .静态成员和实例成员

构造函数中可以添加成员,可以在构造函数本身上添加,也可以在构造函数内部的this上添加,通过这两种方式添加的成员,就分别叫做静态成员和实例成员。
静态成员:在构造函数本身上添加的成员叫静态成员,只能由构造函数本身访问。
实例成员:在构造函数内部通过this创建的对象成员称为实例成员,只能由实例化的对象来访问。

3 .构造函数原型 prototype

构造函数通过原型分配的函数是所有对象共享的。
JS规定,每一个构造函数都有一个prototype属性,指向另一个对象,注意这个prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。我们可以把那些不变的方法,直接定义到原型对象上,这样所有对象的实例,就可以共享这些方法。

function Star (uname, age) {this.uname = uname;this.age = age;
}
Star.prototype.sing = function(){ console.log("sing") };
Star.prototype.movie = function(){ console.log("movie") };
new Star("name", 18);

4 .对象原型 _ _proto _ _

对象都有一个属性 _ _proto _ _指向构造函数的prototype原型对象,之所以我们对象可以使用构造函数原型对象prototype中的属性和方法,就是因为对象由 _ _proto _ _原型的存在。
_ _proto _ _对象原型和原型对象prototype是等价的。
_ _proto _ _对象原型的意义就是为对象的查找机制提供一个方向,或者说一条路线,但是他是一个非标准属性,因此,实际开发中,不可以使用这个属性,它只是内部指向了原型对象prototype。

5 .constructor构造函数

_ _proto _ _对象原型和构造函数的原型对象prototype内都由一个constructor属性,我们称之为构造函数,因为它指回构造函数本身。
constructor主要用于记录该对象引用哪个构造函数,它可以让原型对象重新指回构造函数。很多情况下需要我们手动利用constructor指回原来的构造函数。

function Star (uname, age) {this.uname = uname;this.age = age;
}
// Star.prototype.sing = function(){ console.log("sing") };
// Star.prototype.movie = funciton(){ console.log("movie") };
// 修改了原型对象,并且用对象形式赋值,就会改变构造函数中constructor的指向,这个时候就需要手动指回本来的构造函数
Star.prototype = {constructor: Star,sing: function() { console.log("sing") },movie: function() { console.log("movie") }
}new Star();

6 .原型链


7.继承
ES6之前并没有提供extends继承,是通过构造函数和原型对象模拟实现继承,称为组合继承
①call方法
call()方法可以用来调用函数,并改变函数内this的指向。

fun.call("当前调用函数的this的指向对象", arg1, arg2...);

组合继承的核心原理就是借用call方法,将父构造函数的this指向子构造函数的this

function Father(uname, age) {this.uname = uname;this.age = age
}
Son.prototype = new Father(); /* 继承方法, 将父构造函数的实例对象赋值给子构造函数,子构造函数
可以通过父构造函数的原型对象来间接访问父构造函数的方法,同时,双方方法的改变不会相互影响,
但这种方法会改变子构造函数的congstructor指向 */
Son.prototype.constructor = Son; // 手动指回
function Son (uname, age) {Father.call(this, uname, age); // 继承属性
}
var s = new Son("rose", 18);

(五)ES5新增方法
1 .数组方法

①迭代方法 ,map() , every()
forEach() 相当于加强版的for循环

var arr = [1, 2, 3];
arr.forEach(function(item, index, array) {// item: 被遍历数组中的每一个数组元素// index: 每个元素的索引号// array: 被遍历数组本身
})

filter(),用来筛选数组,并返回相应的结果(数组)

var arr = [1, 2, 3];
var result = arr.filter(function(item, index, array) {// item: 被遍历数组中的每一个数组元素// index: 每个元素的索引号// array: 被遍历数组本身return item > 2;
})
console.log(result); // [3]

some()用于查找数组中是否有满足条件的元素,当查找到第一个时,结束循环,它的返回值是true或false

var arr = [1, 2, 3];
var result = arr.some(function(item, index, array) {// item: 被遍历数组中的每一个数组元素// index: 每个元素的索引号// array: 被遍历数组本身return item > 2;
})
console.log(result); // true

2 .字符串方法

①str.trim();方法用于删除字符串两端的空白字符,并不影响原字符串,返回一个处理后的新字符串。

3 . 对象方法
①Object.keys(obj)用于获取对象自身所有的属性,效果类似for…in,返回一个由属性名组成的数组

②Object.defineProperty();用于定义对象的新属性或者修改原有属性。

// Object.defineProperty(目标对象, "需定义或修改的属性的名字", {特性});
var obj = {id: 1,pname: "abc";price: 999
}
Object.defineProperty(obj, "pname", {value: "ipone",writable: false,enumerable: true,configurable: false
})

特性:
value: 设定属性的值,默认为undefined
writable: 值是否可以重定义,默认为false
enumerable: 此属性是否可以被枚举/遍历,默认为false
configurable: 目标属性是否可以被删除,或再次修改特性,默认为false

(六)函数进阶
1 .函数的定义和调用
①命名函数:通过function关键字来定义函数

// 定义
function fn() {};
// 调用
fn();

②匿名函数:通过函数表达式来定义函数

// 定义
var fn = function () {};
// 调用
fn();

③利用new Function(“参数1”, “参数2”, “函数体”);来定义函数

// 定义
var fn = new Function("console.log('形参和函数体必须以字符串的方式传递')");
// 调用
fn();

2 .函数内部this的指向
①call()方法
②apply()方法可以调用一个函数,并改变函数内部this的指向,和call方法不同的是,它可以传入一个数组作为参数。

fn.apply('在函数运行时指定的this值', [数组参数]);

apply方法的主要应用:比如借助apply调用Math对象来求一个数组的最大值

var array = [10, 30, 22];
Math.max.apply(null, array);
// 严格模式下是不允许this指向为null的
// Math.max.apply(Math, array);

③bind()方法同样可以改变函数内部的this指向,它最大的区别是,不会调用函数,它返回改造完成后的原函数的拷贝。

var fun = fn.bind('在函数运行时指定的this值', arg1..);

3 . 严格模式
ES5的严格模式(strct mode),是采用具有限制性JS变体的一种方式,即在严格的条件下运行JS代码。
严格模式可以应用到整个脚本或者个别函数中,因此在使用中,我们可以将严格模式分为为脚本开启严格模式和为函数开启严格模式两种情况。
开启严格模式:

"use strict";

4 .高阶函数
高阶函数是对其他函数进行操作的函数,它接收函数作为参数,或将函数作为返回值输出。

5 .闭包
闭包是指有权访问另一个作用域中变量的函数。
闭包的作用就是用来延申变量的作用范围。

利用闭包获取当前元素的索引号:

<body><ul><li>1</li><li>2</li><li>3</li><li>4</li></ul><script>var lis = document.querySelector("ul").querySelectorAll("li");lis.forEach(function(items, index) {(function() {items.addEventListener("click", function(){console.log(index);})})(index);          })</script>
</body>

6 .递归
如果一个函数在内部可以调用其本身,那么这个函数就称为递归函数。
递归的效果和循环类似,所以很容易发生栈溢出错误(死循环),一定要加return退出条件。

var n = 1;
function fn() {console.log(`第${n}次循环`);if(n === 5) {return false;}n++;fn();
}
fn();

利用递归求1~n的阶乘

function fn(n) {if (n == 1) {return 1;}return n * jn(n - 1);
}
fn();

(七)浅拷贝和深拷贝
浅拷贝:复杂数据类型只拷贝地址

var obj = {id: 1,uname: "duke",message: { age: 18 }
}
var newObj = {};
for (var key in obj) {newObj[key] = obj[k];
}//ES6新增
Object.assign(newObj, obj);

深拷贝:数据完全复刻,重新开辟内存空间,实现的思路还是函数递归

var obj = {id: 1,uname: "duke",message: { age: 18 },hobby: ["抽烟", "喝酒", "烫头"],
}
var newObj = {};
function deepCopy(newObj, oldObj) {for (var k in oldObj) {var item = oldObj[k];if(item intanceOf Array) {newObj[k] = [];deepCopy(newObj[k], item);} else if (item intanceOf Object) {newObj[k] = {};deepCopy(newObj[k], item);} else { newObj[k] = item;}}
}
deepCopy(newObj, obj);

我的前端自学之路 JavaScript面向对象相关推荐

  1. 前端自学之路 Javascript 行话浅析(一)——字面量 包装对象 作用域

    文章目录 直接量(literal) Undefine NULL 包装对象 变量作用域 函数作用域 块级作用域 作用域链 变量解析 引用错误 本篇主要涉及较为基础的, 变量, 作用域方面的名词. 为啥要 ...

  2. 一个「学渣」从零开始的Web前端自学之路

    从 13 年专科毕业开始,一路跌跌撞撞走了很多弯路,做过餐厅服务员,进过工厂干过流水线,做过客服,干过电话销售可以说经历相当的"丰富". 最后的机缘巧合下,走上了前端开发之路,作为 ...

  3. 一个「学渣」从零Web前端自学之路

    从 13 年专科毕业开始,一路跌跌撞撞走了很多弯路,做过餐厅服务员,进过工厂干过流水线,做过客服,干过电话销售可以说经历相当的"丰富". 最后的机缘巧合下,走上了前端开发之路,作为 ...

  4. 一个「学渣」的从零Web前端自学之路,附学习资源分享

    从 13 年专科毕业开始,一路跌跌撞撞走了很多弯路,做过餐厅服务员,进过工厂干过流水线,做过客服,干过电话销售可以说经历相当的"丰富". 最后的机缘巧合下,走上了前端开发之路,作为 ...

  5. 我的web前端自学之路-心得篇:我为什么要学习web前端?

    时光如流水,转眼间,自己已经是大三的学长了,看着一个个学弟学妹,心中有种莫名的感觉,很怀念大学的前两年时光,但也很憧憬着自己的未来,自己将要去经历很多从未经历的事.我是我们学校信科院的一名学生,在编程 ...

  6. 我是如何从零开始 Web 前端自学之路的?

    作者 | 六小登登 责编 | 屠敏 从 2013 年专科毕业开始,一路跌跌撞撞走了很多弯路,做过餐厅服务员,进过工厂干过流水线,做过客服,干过电话销售可以说经历相当的"丰富". 最 ...

  7. 【干货】前端自学之路(持续更新)

    前言:将我有过了解前端自学网站和书本分享给大家,互联网是个好东西,多多利用:希望能给大家提供一点帮助作为我对大家七夕的祝福,好好学习,天天向上.共勉,哈哈. mooc网站(看视频) 慕课网:http: ...

  8. web前端自学之路分享

    前言: 2018年随着编程的火热和自身对这岗位的热爱,这一年毅然决然的开始了自己的自学之路,这一阶段的学习过程中有很多感触,随着工作逐步稳定想要写下来和正在学习或者正在犹豫要不要学习的人们一起分享.也 ...

  9. Web前端自学之路学习路线,web前端开发网站

    前端开发作为一个由网页制作演变成的新兴岗位,其实在国内外来说,受到重视的时间并不长,在前几年间技术快速的发展和其应用普及率的迅猛增长,使得前端人才市场一片盛况空前的景象,由于其的易入门性和不错的发展前 ...

最新文章

  1. Linux下tar解压到当前目录,zip压缩,tar压缩,tar解压
  2. 必看!这八则故事教会你如何理财
  3. 查看unlix服务器host文件,php代码优化及php相关问题总结
  4. 【运筹学】线性规划 人工变量法 ( 人工变量法案例 | 第三次迭代 | 中心元变换 | 检验数计算 | 最优解判定 )
  5. C#封装WebBrowser时NewWindow事件无法获取Url的解决方法
  6. misc高阶 攻防世界_攻防世界 Misc 进阶题(一)
  7. github gists 101使代码共享漂亮
  8. [BUGKU][CTF][PWN][2020] PWN writeup
  9. 理性分散投资 收益袋袋平安
  10. 在golang中defer、panic与recover的作用
  11. 一些常用算法 练手的的代码
  12. Gin 快速入门知识点总结(奇淼)
  13. 在cmd里面运行adb命令的时候提示:adb server is out of date. killing...
  14. 接口测试基础思维导图
  15. 8种教你如何快速提高平面设计技巧
  16. 海底捞“清疮”300店:千亿龙头的虚与实
  17. 计算机小写换大写函数,excel小写换大写函数的教程
  18. pycharm中python的默认安装路径_PyCharm下载和安装详细步骤
  19. 磁盘管理器显示状态良好 计算机不显示,win7系统打开磁盘管理显示显示状态良好(有危险)的解决方法...
  20. Oracle同义词的好处

热门文章

  1. 如何操作知识付费网课分销
  2. 接口自动化测试工具-Apifox 基础篇:简介
  3. 【学生请假系统——开题报告 分享(仅供参考呀)】
  4. VMware软件虚拟机不能全屏的问题
  5. 图片怎么弄成pdf格式文件
  6. 英伟达收购,ARM也要变美国公司,国产芯出路几何?
  7. 六一送好书|Cocos小粉丝回馈季来啦!
  8. MySQL高级性能优化
  9. 软碟通刻录光盘作为系统盘 失败
  10. Python快速教程 - 基础篇