面向对象
什么是面向对象编程(OOP)?用对象的思想去写代码,就是面向对象编程。
面向对象编程的特点
抽象:抓住核心问题
封装:只能通过对象来访问方法
继承:从已有对象上继承出新的对象
多态:多对象的不同形态
四大基本特性:
抽象:提取现实世界中某事物的关键特性,为该事物构建模型的过程。对同一事物在不同的需求下,需要提取的特性可能不一样。得到的抽象模型中一般包含:属性(数据)和操作(行为)。这个抽象模型我们称之为类。对类进行实例化得到对象。
封装:封装可以使类具有独立性和隔离性;保证类的高内聚。只暴露给类外部或者子类必须的属性和操作。类封装的实现依赖类的修饰符(public、protected和private等)
继承:对现有类的一种复用机制。一个类如果继承现有的类,则这个类将拥有被继承类的所有非私有特性(属性和操作)。这里指的继承包含:类的继承和接口的实现。
多态:多态是在继承的基础上实现的。多态的三个要素:继承、重写和父类引用指向子类对象。父类引用指向不同的子类对象时,调用相同的方法,呈现出不同的行为;就是类多态特性。多态可以分成编译时多态和运行时多态。
抽象、封装、继承和多态是面向对象的基础。
在面向对象四大基础特性之上,我们在做面向对象编程设计时还需要遵循有一些基本的设计原则。对象的组成属性:对象下面的变量叫做对象的属性方法:对象下面的函数叫做对象的方法this 当前发生事件的对象,当前的方法属于谁,函数属于谁```javascript
面向对象的概念:
理解面向对象:
(1) 面向对象是相对于面向的过程而言的。
(2)面向过程和面向对象都是强调的一种思想。
(3) 面向过程:强调的是功能的行为。
(4)面向对象是基于面向过程的。
(5) 面向对象是基于面向过程的。
面向对象特点
1、是一种符合人们思考习惯的思想。
2、将复杂的问题简单化。
3、使程序员从动作的执行者变为动作的指挥者。
4、完成指定的需求时:
先去找具有所需功能的对象来用。
如果该对象不存在,那么创建一个具有所需功能的对象。
这样简化了开发并且提高了复用性。
面向对象开发、设计、过程
开发过程:其实就是不断的创建对象、调用对象、指挥对象做事情。
设计过程:其实就是在管理和维护对象与对象之间的关系。
面向对象的特性:
继承、封装、多态、抽象也算
## js的基本类型有哪些?引用类型有哪些?null和undefined的区别。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210208143224241.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MDc0MTE4,size_16,color_FFFFFF,t_70)
## 判断数据类型
```javascript
typeof
typeof 是一个操作符,其右侧跟一个一元表达式,并返回这个表达式的数据类型。返回的结果用该类型的字符串(全小写字母)形式表示,包括以下 7 种:number、boolean、symbol、string、object、undefined、function 等。
typeof ''; // string 有效
typeof 1; // number 有效
typeof Symbol(); // symbol 有效
instanceof
[] instanceof Array; // true
{} instanceof Object;// true
new Date() instanceof Date;// true
function Person(){};
new Person() instanceof Person;
[] instanceof Object; // true
new Date() instanceof Object;// true
new Person instanceof Object;// true
constructor
“”.constructor = String
new Number(1).constructor = Number
[].constructor = Array
toString
Object.prototype.toString.call('') ; // [object String]
Object.prototype.toString.call(1) ; // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(Symbol()); //[object Symbol]
Object.prototype.toString.call(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
判断所有数据类型
getType([ ]) 返回 ‘array’
getType(2) 返回 ‘number’
function getType(obj){
var s = Object.prototype.toString.call(obj);
return s.slice(s.indexOf(" ")+1,s.length-1).toLowerCase();
}
如何判断一个变量是Array类型?如何判断一个变量是Number类型?(都不止一种)。
从原型入手,Array.prototype.isPrototypeOf(obj);也可以从构造函数入手,objinstanceofArray根据对象的class属
性(类属性),跨原型链调用toString()方法。Array.isArray()方法。
isNaN()是一个函数,用isNaN判断一个变量,返回一个Boolean值。若返回的值为false,则为可以转换成数字
类型;返回的值是true,则不能转换成数字类型
Typeof() 判断
js兼容性问题
JS常见的兼容性问题汇总
1> 滚动条:
document.documentElement.scrollTop || document.body.scrollTop
1
2> 获取样式兼容
function getStyle(dom, styleName){
return dom.currentStyle? dom.currentStyle[styleName] : getComputedStyle(dom)[styleName];
}
3> 网页可视区域兼容
window.innerHeight || document.documentElement.clientHeight
window.innerWidth || document.documentElement.clientWidth
4) 事件对象兼容
evt = evt || window.event;
5) 阻止事件冒泡兼容
event.stopPropagation ? event.stopPropagation() : event.cancelBubble=true;
6)阻止默认行为兼容
evt.preventDefault?evt.preventDefault():evt.returnValue=false;
7)事件监听兼容
if(document.all){
dom.attactEvent(“onclick”, fn);
} else {
dom.addEventListener(“click”, fn);
}
Object是引用类型嘛?引用类型和基本数据类型有什么区别?堆栈关系了解吗?。
JS常见的DOM操作API?
解释一下事件冒泡和事件捕获?
事件冒泡: 当你使用事件捕获时,父级元素先触发,子级元素后触发。 事件捕获:当你使用事件冒泡时,子级元素先触发,父级元素后触发。
事件委托(手写例子),事件冒泡和捕获,如何阻止冒泡?如何阻止默认事件?
对闭包的理解?什么时候构成闭包?闭包的实现方法?闭包的优缺点?
this有哪些使用场景?跟C,JAVA中的this有什么区别?如何改变this的指向?
var number = 50;
var obj = {
number:2,
getNum:function(){
var number = 6
return this.number
}
}
console.log(obj.getNum())//2 this指的是obj
console.log(obj.getNum.call())//50 如果传入null也是50 this指的是windows
console.log(obj.getNum.call({
number:7}))//7 this的当前传入的对象
call,apply,bind有什么区别?
自定义call,apply,bind
自定义 call 函数
Function.prototype.myCall = function (context) {
var context = Object(context) || window;
// 传递this指向
context.fn = this;
// 传递参数
var args = [...arguments].slice(1);
var result = context.fn(...args);
delete context.fn;
return result;
};
自定义apply
Function.prototype.myApply = function (context, args) {
var context = Object(context) || window;
context.fn = this;
var result = "";
// 由于apply的传参方式同call不同
// 原方法的参数是以数组形式传递
// 所以需要判断一下
if (args) {
result = context.fn(...args);
} else {
result = context.fn();
}
delete context.fn;
return result;
};
自定义 bind 函数
Function.prototype.myBind = function (context) {
if (typeof this !== "function") {
// 判断this指向的是否是方法,如果不是抛出类型错误
throw new TypeError("Err");
}
var self = this;
// bind的参数传递方法有两种
// 1.bind调用时传参
var arg1 = [...arguments].slice(1);
const bindFn = function () {
// 2.调用bind返回的方法时再传参
var arg2 = [...arguments];
// 拼接bind所有可能的参数
return self.myApply(context, arg1.concat(arg2));
};
// bind方法返回的是一个新方法
return bindFn;
};
函数的作用域是什么?JS的作用域你了解吗?
Js如何实现重载和多态?
显示原型和隐式原型,手绘原型链,原型链是什么?为什么要有原型链?
你知道哪几种创建对象的方式?
实现继承有哪些方式,他们的优缺点是什么?
一.原型继承
function Parent(){
this.color = 'red'
}
Parent.prototype.getName = function(){
console.log(this.name)
}
function Child(){
}
Child.prototype = new Parent();//将父类的实例赋给子类的原型
var child1 = new Child();
child1;
二.借用构造函数
function Parent(name){
this.name = name;
this.colors = ['red','green','pink'];
}
Parent.prototype.getName = function(){
console.log(this.name)
}
function Child(){
Parent.call(this,'Mary');//使用call()方法继承父类构造函数中的属性
this.age = '18';
}
var child1 = new Child();
var child2 = new Child();
三 组合继承
function SuperType(name) {
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function() {
alert(this.name);
}
function SubType