今日学习路线

  • 1.了解面向对象的三大特征

    • 封装

      • 将某个具体功能封装在对象中,只对外部暴露指定的接口,外界在使用的时候,只考虑接口怎么用,不用考虑内部怎么实现
    • 继承
      • 一个对象拥有其他对象的属性和方法
    • 多态
      • 一个对象在不同情况下的多种状态
  • 2.了解原型链
    • 原型链的作用:实现继承

      • js是通过原型链来实现继承的

01-面向对象三大特征(继承)

1.1-面向对象三大特征介绍

​ a.封装:将某个具体功能封装在对象中,只对外部暴露指定的接口,外界在使用的时候,只考虑接口怎么用,不用考虑内部怎么实现(前面学习的api其实就是一种封装思想)
​ b.继承:一个对象拥有其他对象的属性和方法
​ c.多态:一个对象在不同情况下的多种状态

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><script>/*面向对象三大特征a.封装:将某个具体功能封装在对象中,只对外部暴露指定的接口,外界在使用的时候,只考虑接口怎么用,不用考虑内部怎么实现b.继承:一个对象拥有其他对象的属性和方法c.多态:一个对象在不同情况下的多种状态*//*多态(了解即可,使用不多):一个对象在不同情况的多种状态饲养员对象Person : 给动物对象喂养食物  funtion work(animal,food){ animal.eat(food) }动物对象Animal : 吃东西  eat(food){ }多态 : 给不同的动物喂养食物,虽然都是调用eat()方法,但是不同的动物会执行不同的eat()*///示例:饲养员给动物喂食物//动物function Animal ( name ) {this.name = name;};//猫let cat = new Animal('猫咪');cat.eat = function ( food ) {console.log ( "喵喵猫" + "我吃了" + food );};//狗let dog = new Animal('小狗狗');dog.eat = function ( food ) {console.log ( "汪汪汪" + "我吃了" + food );};//饲养员function Person (  name ) {this.name = name;};Person.prototype.work = function (animal,food ) {//animal接收一个由Anmiaml构造函数生成的实例化对象,调用它的eat方法//同一对象表现出来不同的状态,就叫做多态animal.eat(food);};let p1 = new Person('ikun');p1.work(cat, '饼干');p1.work(dog, '翔');</script>
</body>
</html>

1.2-继承的三种实现方式

  • 继承:让一个对象拥有另一个对象的属性和方法
  • 本小节知识点
    • 1.混入式继承 : 遍历 父对象 的所有属性值,添加给 子对象

      • 特点:每继承一次,就要执行一次循环
      • 应用场景:单个对象继承
    • 2.替换原型继承 : 将 父对象 作为 子对象构造函数的原型
      • 特点:会丢失原型之前的成员变量
      • 应用场景:多个对象继承
    • 3.混合式继承 : 混入式 + 替换原型
      • 特点 : 遍历 父对象 所有的属性值,添加给 子对象构造函数 的原型

1.混入式继承

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><script>/*学习目标 : 继承的三种实现方式 1.混入式继承 : 遍历 父对象 的所有属性值,添加给 子对象特点:每继承一次,就要执行一次循环应用场景:单个对象继承2.替换原型继承 : 将 父对象 作为 子对象构造函数的原型特点:会丢失原型之前的成员变量应用场景:多个对象继承3. 混合式继承 : 混入式 + 替换原型特点 : 遍历 父对象 所有的属性值,添加给 子对象构造函数 的原型*///继承:让一个对象拥有另一个对象的属性和方法let father = {house:{address:'北京一环',price:100000000},car:{brand:'劳斯莱斯',price:5000000}}let son = {name:'ikun',age:30}//1.混入式//解决方案:遍历父对象的所有属性值,添加给子对象//特点:每继承一次,就要执行一次循环//应用场景 : 单个对象继承for (let key in father){father[key] = son[key]}console.log ( son )</script>
</body>
</html>

2.替换原型继承

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body><script>//2.替换原型//解决方案:将父对象作为子对象构造函数的原型//特点:会丢失原型之前的成员变量//应用场景:多个对象继承let father = {house:{address:'北京一环',price:100000000},car:{brand:'劳斯莱斯',price:5000000}}function Son (name,age  ) {this.name = namethis.age = age}Son.prototype.sayHi = function(){console.log('你好')}//让父对象成为子对象构造函数的原型Son.prototype  = father//实例化对象let son1 = new Son('ikun',30)console.log ( son1 )let son2 = new Son('班长',20)console.log ( son2 )</script>
</body>
</html>

3.混合式继承

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body><script>/*学习目标 : 继承的三种实现方式 1.混入式继承 : 遍历 父对象 的所有属性值,添加给 子对象特点:每继承一次,就要执行一次循环应用场景:单个对象继承2.替换原型继承 : 将 父对象 作为 子对象构造函数的原型特点:会丢失原型之前的成员变量应用场景:多个对象继承3. 混合式继承 : 混入式 + 替换原型特点 : 遍历 父对象 所有的属性值,添加给 子对象构造函数 的原型*///3.  混合式(混入+替换原型)//解决方案:遍历父对象所有的属性值,添加给子对象构造函数的原型let father = {house:{address:'北京一环',price:100000000},car:{brand:'劳斯莱斯',price:5000000}}function Son (name,age  ) {this.name = namethis.age = age}Son.prototype.sayHi = function(){console.log('你好')}//将父对象的所有属性添加到子对象构造函数的原型中for(let key in father){Son.prototype[key] = father[key];}//实例化对象let son1 = new Son('ikun',30)console.log ( son1 )let son2 = new Son('班长',20)console.log ( son2 )</script>
</body>
</html>

02-原型链

1.1-原型链介绍

  • 本小节知识点

    • 1.原型链:每一个对象都有原型,原型本身又是对象,所以原型又有原型,以此类推形成一个链式结构,称为原型链
    • 2.对象访问原型链中的成员规则:就近原则
      • 当访问一个对象的成员变量时,会首先访问它自身的成员变量,如果有则访问。没有则在原型中寻找,能找到就访问,不能找到则继续往原型的原型中寻找,以此类推,如果找到原型链的顶端还是找不到,则程序报错:xxx is not a function

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body><script>/* 1.原型链 :每一个对象,都有__proto__指向自身的原型。 而原型也是对象,也有自己的__proto__指向原型的原型,以此类推形成链式结构,称之为原型链。2.对象访问原型链中成员的规则 :就近原则当访问对象的成员,先看自己有没有。有则访问,没有则看原型有没有。原型有则访问,没有则访问原型的原型,没有则继续往上找。以此类推,一直找到原型链终点 : null.还没有, 如果是属性 : 则获取undefined  如果是方法 ,则报错xxx is not defined *///1.构造函数function Person(name,age){this.name = name;this.age = age;};//2.原型对象Person.prototype.sayHi = function(){console.log('人生若只如初见,何事秋风悲画扇');};Person.prototype.type = '哺乳动物';//3.实例化对象let p1 = new Person('又又',18);console.log(p1);//请说出以下代码执行结果console.log(p1.name);//又又      p1自己有name属性console.log(p1.type);//哺乳动物   p1自己没有type,但是p1的原型有console.log(p1.hobby);//undefined p1自己没有hobby,原型也没有p1.sayHi();// 人生若只如初见,何事秋风悲画扇   p1自己没有这个方法,原型有// p1.eat();//报错 xxx is not defined    p1自己没有这个方法,原型也没有//为什么不报错?  p1自己没有这个方法,原型也没有这个方法,但是原型的原型有p1.toString();//查看p1的原型链console.log(p1.__proto__.constructor);//Personconsole.log(p1.__proto__ === Person.prototype);//true//查看p1的原型的原型console.log(p1.__proto__.__proto__.constructor);//Objectconsole.log(p1.__proto__.__proto__ === Object.prototype);//true//查看p1的原型的原型的原型console.log(p1.__proto__.__proto__.__proto__);//null</script>
</body>
</html>

1.2-原型链详解:内置对象的原型链

  • 本小节知识点:内置对象的原型链(附图解说明)

    • 1.通过查看Array的原型链

      • 了解构造函数的原型本身是一个对象,只要是对象就有原型
    • 2.通过查看Date的原型链
      • 学会举一反三,所有的内置对象(Math Array 基本包装类型等)的原型链都是一样的,最终都指向Object
    • 3.通过查看String的原型链:了解这里的String值得是内置对象String(是一个基本包装类型),其他的Number、Boolean原型链和String是一样的
      • 只有对象才有原型,这里一定要把基本数据类型string、number、boolean,和基本包装类型(特殊的引用类型对象)String、Number、Boolean区分开来,不要搞混淆
  • 思考题:为什么arr.toString()方法和对象的toString()方法得到的结果不同
    答:前者属于Array类中的原型对象中的方法,后者为Object类中原型对象中的方法,原型链往上找时会先找到Array类中的toString()方法

1.Array的原型链

//1.Arraylet arr = new Array(10,20,30);console.log ( arr );//查看arr的原型console.log ( arr.__proto__.constructor );//Arrayconsole.log ( arr.__proto__ === Array.prototype );//查看arr的原型的原型console.log ( arr.__proto__.__proto__.constructor );//Objectconsole.log ( arr.__proto__.__proto__ === Object.prototype );//true

2-Date的原型链

//2.Datelet date1 = new Date();//细节:日期对象直接console.log会转成string,查看对象需要使用console.dir打印console.dir(date1);console.log ( date1.__proto__ === Date.prototype );//trueconsole.log ( date1.__proto__.__proto__.constructor );//Objectconsole.log ( date1.__proto__.__proto__ === Object.prototype );//true

3-String对象原型链

//3.Stringlet str = new String('123');console.log ( str );console.log ( str.__proto__ === String.prototype );//trueconsole.log ( str.__proto__.__proto__.constructor );//Objectconsole.log ( str.__proto__.__proto__ === Object.prototype );//true

4-DOM对象原型链

//4.界面元素let div1 = document.getElementById('div1');let p1 = document.getElementById('p1');

  • 完整代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><div id="div1"></div>
<p id="p1"></p><script>/*查看内置对象的原型链*///1.Arraylet arr = new Array(10,20,30);console.log ( arr );//查看arr的原型console.log ( arr.__proto__.constructor );//Arrayconsole.log ( arr.__proto__ === Array.prototype );//查看arr的原型的原型console.log ( arr.__proto__.__proto__.constructor );//Objectconsole.log ( arr.__proto__.__proto__ === Object.prototype );//true//2.Datelet date1 = new Date();//细节:日期对象直接console.log会转成string,查看对象需要使用console.dir打印console.dir(date1);console.log ( date1.__proto__ === Date.prototype );//trueconsole.log ( date1.__proto__.__proto__.constructor );//Objectconsole.log ( date1.__proto__.__proto__ === Object.prototype );//true//3.Stringlet str = new String('123');console.log ( str );console.log ( str.__proto__ === String.prototype );//trueconsole.log ( str.__proto__.__proto__.constructor );//Objectconsole.log ( str.__proto__.__proto__ === Object.prototype );//true//4.界面元素let div1 = document.getElementById('div1');let p1 = document.getElementById('p1');</script>
</body>
</html>

1.3-instanceof运算符

本小节知识点

  • instanceof语法: 对象 instanceof 构造函数
  • 作用:检测构造函数的原型prototype在不在这个对象的原型链上
 //1.示例let arr = [10,20,30];//数组原型链  arr->Arr.prototype->Object.prototype->nullconsole.log ( arr instanceof Array );//trueconsole.log ( arr instanceof Object );//true//2.示例//根据instanceof语法:左边Function表示对象,右边Function表示构造函数//Function原型链  Function对象->Function.prototype->Object.prototype->nullconsole.log ( Function instanceof Function );//trueconsole.log ( Function instanceof Object );//true//3.示例//根据instanceof语法:左边Object表示对象,右边Object表示构造函数//Object原型链 Object对象->Function.prototype->Object.prototype->nullconsole.log ( Object instanceof Object );//trueconsole.log ( Object instanceof Function );//true

03-ES6类与继承

1.1-class关键字介绍

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head><body><script>/* 1.学习目标1.1 class关键字作用: 声明一个类函数* 相当于ES5的构造函数,只是代码的阅读性大大提高* a. 把构造函数和原型全部写在一个大括号里面,提高代码阅读性* b. 必须要使用new才可以调用class函数,提高代码规范1.2 class关键字语法:class 构造函数名{constructor(){//(1)这里写构造函数代码};//(2)原型里面的方法写在下面eat(){};play(){};};2.学习路线:对比法2.1 ES5 构造函数与原型语法2.2 ES6 构造函数与原型语法*///1.ES5得构造函数与原型写法// //(1)构造函数// function Person(name,age){//     this.name = name;//     this.age = age;// };// //(2)给原型添加方法// Person.prototype.eat = function(){//     console.log('大吉大利今晚吃鸡');// };// Person.prototype.sayHi = function(){//     console.log('你好,我是黑马李宗盛');// };// //(3)实例对象// let p1 = new Person('ikun',30);// console.log(p1);//2. ES6的构造函数写法//(1)声明类Personclass Person {//(1) 构造函数  : 名字必须叫做 constructorconstructor(name, age) {this.name = name;this.age = age;};//(2) 给原型添加方法  : 方法名(){}sayHi() {console.log('你好,我是黑马李宗盛');};eat() {console.log('大吉大利今晚吃鸡');};};/* 细节: class本质其实就是构造函数的另一种写法,本质还是给prototype添加成员使用了class,一样可以继续使用ES5的prototype*/Person.prototype.type = '人类';//(3)实例对象let p1 = new Person('ikun', 30);console.log(p1);</script>
</body></html>

1.2-extends关键字介绍

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head><body><script>/* 学习目标:  extends关键字1.作用:  继承2.底层原理: 替换原型继承*///(1)声明类Personclass Person {//(1) 构造函数  : 名字必须叫做 constructorconstructor(name, age) {this.name = name;this.age = age;};//(2) 给原型添加方法  : 方法名(){}sayHi() {console.log('你好');};eat() {console.log('大吉大利今晚吃鸡');};};Person.prototype.type = '人类';//(3)实例对象let p1 = new Person('ikun', 30);console.log(p1);/* extends关键字 *///声明一个类函数 Student  继承于  Person 类函数//底层原理相当于  Student.prototype.__proto__ = Person.prototypeclass Student extends Person{//Student原型添加方法learn(){console.log('今天学的很开心');};};let s1 = new Student('班长',20);console.log(s1);s1.learn();//s1自己没有learn,但是原型有s1.eat();//s1自己没有eat,原型没有eat, 但是原型的原型有eat</script>
</body></html>

1.3-super关键字介绍

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head><body><script>/* 学习目标:  super关键字1.作用:  子类中调用父类的方法2.底层原理: 函数上下文调用*///(1)声明类Personclass Person {//(1) 构造函数  : 名字必须叫做 constructorconstructor(name, age) {this.name = name;this.age = age;};//(2) 给原型添加方法  : 方法名(){}sayHi() {console.log('你好');};eat() {console.log('大吉大利今晚吃鸡');};};Person.prototype.type = '人类';//(3)实例对象let p1 = new Person('kiki', 18);console.log(p1);/* super关键字 : 子类中调用父类的方法如果在子类中,也写了 constructor函数,则必须要调用  super()否则程序报错*//* 声明子类Student 继承 父类 Person */class Student extends Person{//子类构造函数constructor(name,age,score){/* 注意点:如果子类也写了constructor,则必须要调用super */super(name,age);this.score = score;}//Student原型添加方法learn(){console.log('1.我要吃饭了');//调用Person原型中的eat()//底层原理: Person.call(this)super.eat();console.log('3.我开始学习了'); };};let s1 = new Student('班长',20,99);console.log(s1);s1.learn();//s1自己没有learn,但是原型有s1.eat();//s1自己没有eat,原型没有eat, 但是原型的原型有eat</script>
</body></html>

04-函数补充(了解即可)

1.1-arguments关键字

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body><script>/* 1.arguments关键字: 获取函数所有实参* 是一个伪数组* 只能用于函数2.场景 : 例如数组push()方法,传多少实参就给数组添加多少元素。底层原理就是使用arguments实现的*/function fn(){console.log(arguments)}fn(10,20,30,40)</script>
</body>
</html>

1.2-剩余参数(rest参数)

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body><script>/* 1.剩余参数(rest参数) : 获取函数剩余的所有实参* 是一个真数组* 只能写在函数最后形参位置2.场景:大多数情况下, rest参数可以替代argumentsarguments是老语法,浏览器兼容性好rest参数:新语法,有些老的浏览器不支持*/function fn(a,b,...c){console.log(arguments)//获取所有实参 10 20 30 40console.log(a,b)//10 20console.log(c)//[30,40] 获取剩余参数}fn(10,20,30,40)</script>
</body>
</html>

第二天学习总结

  • 1.面向对象三大特征

    • a.封装:将某个功能封装到对象或函数中
    • b.继承:一个对象拥有另一个对象的所有成员变量(属性和方法)
    • c.多态:一个对象在不同情况的多种状态
  • 2.实现继承的几种方式

    • a.混入式继承

      • 解决方案:遍历父对象的所有属性值,添加给子对象
      • 弊端:每继承一次,就要执行一次循环
      • 应用场景:父对象只有一个子对象
    • b.替换原型
      • 解决方案:将父对象作为子对象构造函数的原型
      • 弊端:会丢失原型之前的成员变量
      • 应用场景:自定义内置对象
    • c.混合式(混入+替换原型)
      • 解决方案:遍历父对象所有的属性值,添加给构造函数的原型
      • 应用场景:父对象有多个子对象
  • 3.原型链

    • 原型链:每一个对象都有原型,原型本身又是对象,所以原型又有原型,以此类推形成一个链式结构,称为原型链
  • 对象在原型链中的访问规则:就近原则

    • 当访问对象成员变量时,会先从自己的属性中查找,如果有就访问,没有就访问自己原型的,如果原型中没有,则访问原型的原型,以此类推,如果访问到原型链的顶端还是没有,则程序报错xxxx is not undefined
    • 特殊情况:Object.prototype的原型对象是null
  • d.函数本身也是对象

    • 构造函数属于函数
  • 5.instanceof运算符

    • 语法:对象 instanceof 构造函数
    • 作用:检测构造函数的原型prototype在不在这个对象的原型链上

今天学习重点梳理(面试题)

  • 1.js语言是通过什么技术实现面向对象继承的

    • 答案:原型链
  • 2.原型链终点是什么

    • 答案:null

JS高级进阶总结day02---面向对象编程三大特征,原型链总结相关推荐

  1. JS面向对象编程三大特征

    JS面向对象编程三大特征 JS面向对象的三大特征为封装.继承.多态.下面分别进行介绍: 封装 封装是指创建一个对象集中保存一个事物的属性与功能 继承 继承是指父亲的成员,孩子无需重复创建就可直接使用. ...

  2. 允许使用抽象类类型 isearchboxinfo 的对象_Java面向对象编程三大特征 - 多态

    Java面向对象编程三大特征 - 多态 本文关键字:Java.面向对象.三大特征.多态 多态是面向对象编程的三大特征之一,是面向对象思想的终极体现之一.在理解多态之前需要先掌握继承.重写.父类引用指向 ...

  3. 面向对象编程三大特征之一 继承

    文章目录 继承 概述 语句定义格式 继承的特点 注意事项 继承与成员变量之间的关系 this关键字与super关键字的使用区别 继承与构造方法的关系 继承与成员方法的关系 重写与重载的区别 方法重写的 ...

  4. JS高级进阶总结day01---面向对象编程介绍,new的工作原理以及构造函数,原型对象,实力函数三者之间的关系

    02-面向对象编程 1.1-面向对象编程介绍 本小节知识点 1.理解什么是面向对象编程 面向对象不是一门技术,而是一种解决问题的思维方式 面向对象的本质是对面向过程的一种封装 2.理解什么是对象 对象 ...

  5. Scala进阶之路-面向对象编程之类的成员详解

    Scala进阶之路-面向对象编程之类的成员详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Scala中的object对象及apply方法 1>.scala 单例对象 ...

  6. Python - 面向对象编程 - 三大特性之继承

    继承 继承也是面向对象编程三大特性之一 继承是类与类的一种关系 定义一个新的 class 时,可以从某个现有的 class 继承 新的 class 类就叫子类(Subclass) 被继承的类一般称为父 ...

  7. Day55-每日一道Java面试题-Java 面向对象编程三大特性: 封装 继承 多态

    Java 面向对象编程三大特性: 封装 继承 多态 封装 封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,我们大可不必提供方法给外界访问.但是如果一个类没有 ...

  8. python多态的三种表现形式_python小结----面向对象的三大特征(封装,继承,多态)

    面向对象的三大特征: 封装,继承,多态 面向对象的编程思想核心:高类聚,低耦合–程序的设计模式范畴 封装 什么是封装: 在面向对象编程的思想中,对代码进行高度封装,封装又叫包装 封装就是指将数据或者函 ...

  9. java五大原则_Java面向对象的三大特征和五大原则

    Java面向对象的三大特征 封装 封装(Encapsulation)是指属性私有化,根据需要提供setter和getter方法来访问属性.即隐藏具体属性和实现细节,仅对外开放接口,控制程序中属性的访问 ...

最新文章

  1. 一文了解动态场景中的SLAM的研究现状
  2. 理解域信任关系,Active Directory系列之十六
  3. ZooKeeper私人学习笔记
  4. dom4j读取xml信息
  5. tensorflow 1.X迁移至tensorflow2 代码写法
  6. BZOJ2005 NOI2010 能量采集 欧拉函数
  7. 你需要学好知识图谱----用AI技术连接世界
  8. 信息学奥赛C++语言:社会实践任务
  9. admin后台菜单栏的实现
  10. linux 7 postconf,postconf 命令常用参数
  11. 安装hdfs集群的具体步骤
  12. linux监听apache代码,linux系统使用python监控apache服务器进程脚本分享
  13. 【转】CCScale9Sprite和CCControlButton
  14. python模块-re模块
  15. LVS 三种工作模式
  16. 关于python文件打开模式表示错误的是_python文件读取失败了该怎么处理 !
  17. 荣耀V10什么时候升级鸿蒙,华为非常良心,荣耀V10用户迎来更新,2.08M补丁包优化稳定性...
  18. 【数学】高昆轮高数下强化
  19. 直方图归一化因子计算公式
  20. java 根据excel模板格式导出指定格式的excel

热门文章

  1. Handler消息机制-Native层
  2. 《Editing Text in the wild》学习笔记
  3. 推荐一位大神,手握 GitHub 16000 star
  4. QQ轻聊版、TIM版无法修改个人文件夹位置的解决方法
  5. 平板电脑 中柏4s pro 重装win10 系统
  6. VMware ,centos7能ping通外面,但是外面ping不通里面,且使用工具远程连接不上
  7. 【目标检测】YOLO系列——YOLOv1详解
  8. 5 款必备的免费在线画图工具!超级好用
  9. 解析 Java 类和对象的初始化过程
  10. 「Don‘t Make Me Think」 读后感