IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> DAY20刷面试题 -> 正文阅读

[JavaScript知识库]DAY20刷面试题

JS创建对象对象的方法

1)new一个Object的实例
实例化一个Object对其添加属性和方法,把实例保存在变量person中

var person = new Object();
person.name="zj";
person.age=20;
person.say = function(){
	alert("hi")
}

2)对象字面量模式

var person = {
	name:"zj";
	age:"20";
	say : function(){
		alert(this.name);
	}
}

前两种方法都是用了同一个接口创建很多对象,会产生大量的重复代码

3)工厂模式

function createPerson(name,age,jpb){
	var p = new Object();
	p.name = name;
	p.age = age;
	p.job = job;
	p.say = function(){
		alter(this.name);
	}
	return p;
}
var p1 = createPerson('NCT',18,'singer');
var p2 = createPerson('RV',22,'dancer');

解决了一个一个的创建对象问题,没有解决对象识别问题(怎么知道一个对象的类型)返回的都是Object类型。

4)构造函数模式

function Person(name,age,jpb){//构造函数用大写开头,为了区分别的函数;构造函数本身也是函数,不过能创建对象而已。
	this.name = name;
	this.age = age;
	this.jpb = jpb;
	this.say = function(){
		alert(this.name)
	}
}
var person1 =new Person('NCT',18,'singer');
var person2 =new Person('RV',22,'dancer');

对比工厂模式的区别:

  • 没有显示地创建对象
  • 直接将属性和方法赋给了this对象
  • 没有return语句
  • 可以识别对象的类型使用instanceof操作符

alert(person1 instanceof Object);//ture
alert(person1 instanceof Person);//ture
alert(person2 instanceof Object);//ture
alert(person2 instanceof Object);//ture

缺点:
每个方法都要在每个实例上重新创建一遍,方法指的是在对象里定义的函数,如果方法数量很多就会占用很多不必要的内存。

5)原型创建对象模式

function Person() {
}

Person.prototype.name = "lisi";
Person.prototype.age = 21;
Person.prototype.family = ["lida","lier","wangwu"];
Person.prototype.say = function(){
    alert(this.name);
};
console.log(Person.prototype);   //Object{name: 'lisi', age: 21, family: Array[3]} 

var person1 = new Person();        //创建一个实例person1
console.log(person1.name);        //lisi --来自原型

var person2 = new Person();        //创建实例person2
person2.name = "wangwu";
person2.family = ["lida","lier","lisi"];
console.log(person2);            //Person {name: "wangwu", family: Array[3]} --来自实例
// console.log(person2.prototype.name);         //报错
console.log(person2.age);              //21
function Person(){}
Person.prototype.name = 'Nike';
Person.prototype.age = 20;
Person.prototype.jbo = 'teacher';
Person.prototype.sayName = function(){
 alert(this.name);
};
var person1 = new Person();
var person2 = new Person();
person1.name ='Greg';
alert(person1.name); //'Greg' --来自实例
alert(person2.name); //'Nike' --来自原型

所有对象实例共享它的属性和方法
当为对象实例添加一个属性的时候,这个属性就会屏蔽原型对象中保存的同名属性。

6)组合使用构造函数和原型模式
构造函数模式用于定义实例属性,原型模式用于定义方法和共享的属性。

function Person(name,age,job){
 this.name =name;
 this.age = age;
 this.job = job;
}
Person.prototype = {
 constructor:Person,
 sayName: function(){
 alert(this.name);
 };
}
var person1 = new Person('Nike',20,'teacher');

组合模式共享对相同方法的引用,也保证了每个实例有自己的私有属性,最大限度节省了内存。

JS有哪些数据类型

基本数据类型:Null、Undefined、String、Number、Boolean、Object、Symbol、BigInt(ES6新增)
Symbol:表示创建后独一无二且不可变的数据类型,主要是解决可能出现的全部变量冲突问题。
BigInt:数字类型的数据,表示任意精度格式的整数。超过Number表示的安全数范围也可以。

引用数据类型:Object、Array、Date、Function、RegExp

栈:原始数据类型
堆:引用数据类型(对象、数据、函数)

JS数据类型判断方法

1)typeof
其中数组、对象、null都会被判断为object,其他的判断都正确

console.log(typeof 2);               // number
console.log(typeof true);            // boolean
console.log(typeof 'str');           // string
console.log(typeof []);              // object    
console.log(typeof function(){});    // function
console.log(typeof {});              // object
console.log(typeof undefined);       // undefined
console.log(typeof null);            // object

2)instanceof
可以正确判断对象的引用数据类型,不能判断基本数据类型,其内部运行机制是判断在其原型链中能否找到该类型的原型。

console.log(2 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false 
console.log('str' instanceof String);                // false 
 
console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true

3)constructor

console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true
console.log(([]).constructor === Array); // true
console.log((function() {}).constructor === Function); // true
console.log(({}).constructor === Object); // true

如果创建了一个对象改变了它的原型,constructor就不能用来判断数据类型了。

function Fn(){};
 
Fn.prototype = new Array();
 
var f = new Fn();
 
console.log(f.constructor===Fn);    // false
console.log(f.constructor===Array); // true

4)Object.protype.toString.call()
使用Object对象的原型方法toString来判断数据类型

console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]" 
console.log(Object.prototype.toString.call(null)); // "[object Null]" 
console.log(Object.prototype.toString.call(123)); // "[object Number]" 
console.log(Object.prototype.toString.call("abc")); // "[object String]" 
console.log(Object.prototype.toString.call(true)); // "[object Boolean]"

function fn() {
  console.log("ming");
}
var date = new Date();
var arr = [1, 2, 3];
var reg = /[hbc]at/gi;
console.log(Object.prototype.toString.call(fn));// "[object Function]" 
console.log(Object.prototype.toString.call(date));// "[object Date]" 
console.log(Object.prototype.toString.call(arr)); // "[object Array]"
console.log(Object.prototype.toString.call(reg));// "[object RegExp]"

同样是检测对象obj调用toString方法,obj.toString()的结果和Object.prototype.toString.call(obj)的结果不一样,这是为什么?

这是因为toString是Object的原型方法,而Array、function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串…),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用obj.toString()不能得到其对象类型,只能将obj转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用Object原型上的toString方法。

instanceof 操作符的实现原理以及实现

instanceof运算符用于判断构造函数的prototype属性是否出现在对象的原型链中的任何位置。

function myInstanceof(left,right){
	//获取对象的原型
	let proto = Object.getPrototype(left)
	//获取构造函数的prototype对象
	let prototype = right.prototype;

	//判断构造函数的prototype对象是否在原型链上
	while(true){
		if( !proto )
		return false;
		if( proto === prototype )
		return true;
		//如果没有找到,就继续从其原型上找,Object.getPrototypeOf方法来获取指定对象的原型
		proto = Object.getPrototype(proto);
	}
}

HTML5有哪些更新

1)语义化标签

  • header:定义文档的页面(头部)
  • nav:定义导航链接的部分
  • footer:定义文档或节的页脚(底部)
  • article:定义文章的内容
  • section:定义文档中的节
  • aside:定义其所处内容之外的内容(侧边)
    2)媒体标签
  • audio:音频
  • video:视频
  • source:在video指定视频源
    3)表单
    表单类型
  • email:验证邮箱地址是否合法
  • url:验证URL
  • number:只能输入数字,可以设置max/min/value默认值
  • search:输入框后会给提供一个小叉,可以删除输入的内容
  • color:提供一个颜色拾取器
  • time:时分秒
  • data:日期选择年月日
  • datatime:时间和日期(目前只有safari支持)
  • datatime-local:日期时间控件

表单属性:

  • placeholder:提示信息
  • autofocus:自动获取焦点
  • autocomplete=“on“ 或者 ”off“ 使用前提(表单必须提交过、必须有name属性)
  • required:要求输入框不能为空,有值才能提交。
  • pattern = “ ” 里面写入想要的正则模式,例如手机号"^(+86)?\d{10}$"
  • multiple:可以选择多个文件或者邮箱
  • form = “from表单的ID”

表单事件:

  • oninput:每当input里的输入框内容发生变化都会触发此事件
  • oninvalid:验证不通过时触发此事件

4)DOM查询操作

  • document.querySelector()
  • document.querySelectorAll()

它们选择的对象可以是标签,可以是类(需要加点),可以是ID(需要加#)

5)web存储
localStorage、sessionStorage

CSS3中有哪些新特性

边框:
border-radius:添加圆角边框
border-shadow:给框添加阴影(水平位移,垂直位移,模糊半径,阴影尺寸,阴影颜色,insetr[内/外部阴影])
border-image:设置边框图像
bode-image-source:边框图片的路径
boder-image-repeat:图像边框是否平铺(repeat平铺 round铺满 stretch拉伸)
背景:
background-size:背景图片尺寸
background-origin:规定background-position属性相对于什么位置定位。
background-clip:规定背景的绘制区域(padding-box,border-box,content-box)
渐变:
linear-break:定义如何换行
word-wrap:允许长的内容可以自动换行
text-overflow:当文本溢出包含他的元素时应该干啥
text-shadow:文字阴影(水平位移,垂直位移,模糊半径,阴影颜色)
转换:
transform应用于2D3D转换,可以将元素旋转、移动
缩放、倾斜
transform-origin:可以更改元素转换的位置(xyz轴)
transform-style:指定嵌套元素怎么样在三位空间中呈现
2D转换方法:
rotate旋转translate(x,y)指定元素在二维空间的位移scale(n)定义缩放转换
3D转换方法:
perspective(n)为3D转换translate rotate scale
过渡:
transition-property过去属性名
transition-duration:完成过渡效果需要花费的时间
transition-timing-function:指定切换效果的速度
transition-delay:指定什么时候开始切换效果
动画:
animation-name 为@keyframes动画名称
animation-duration 动画需要花费的时间
animation-timing-function 动画如何完成一个周期
animation-delay 动画启动前的延迟间隔
animation-iteration-count 动画播放次数
animation-direction 是否轮流反向播放动画

vue生命周期

beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
beforeDestroy
destroyed

vue组件传值

父传子
父组件需要把数据绑定:名称 = 值绑定上去
子组件通过props接收

子传父
子组件通过$emit传自定义事件
父组件接收

兄弟传值
公共事件bus
$emit传自定义事件
$on进行接收

Vue的基本原理

当一个vue实例创建是,vue会遍历data中的属性,用Object.defineProperty(vue3使用proxy)将他们转为getter/setter,并且在内部追踪相关依赖,在属性被访问和修改时通知变化。每个组件实例都用相应的watcher程序实例,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的setter被调用的时候,会通知watcher重新计算,从而致使它关联的组件得以更新。

MVC和MVVM的区别

MVC
MVC通过分离Model、View和Controller的方式来组织代码结构。View负责页面显示逻辑,Model负责存储页面的业务数据、以及对应的数据操作。View和Model应用了观察者模式,当Model层发生改变的时候会通知有关View层更新页面。Controller层是View和Model的纽带,主要负责用户与应用的响应操作,当用户与页面产生交互的时候,Controller中的事件触发器就开始工作了,通过调用Model层来完成对Model的修改,然后Model层再去通知View层更新。
MVVM
Model代表数据模型,数据和业务逻辑都在Model层中定义
View代表UI视图,负责数据的展示
ViewModel负责监听Model中数据的改变并且控制视图的更新,处理用户交互操作。

Model和View并无直接关联,而是通过ViewModel来进行联系的,Model和ViewModel之间有着双向数据绑定的联系。因此当Model中的数据改变时会触发View层的刷新,View中由于用户交互操作而改变的数据也会在Mode中同步。
这种模式实现了Model和View的数据自动同步,因此开发者只需要专注于数据的维护操作即可,而不需要自己操作DOM

computed和Watch的区别

computed计算属性:不支持异步,依赖其他的属性值,并且computed值有缓存,只有它依赖的属性值发生改变,下一次获取computed值的时候才会重新计算computed的值。
watch侦听器:支持异步,更多的是观察的作用,无缓存性,类似于某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作。

computed和methods的区别

computed是基于缓存的,如果计算的属性没有变换是不会重新计算的,执行缓存数据。
methods是没有缓存的,也就是只要调用了就会执行该方法。

v-if和v-show的区别

  • v-if是动态的向DOM树内添加或者删除DOM元素;v-show是通过设置DOM元素的display样式属性控制显示或者隐藏。
  • v-if切换有一个局部编译/卸载的过程,切换过程中合适的销毁和重建内部的事件监听和子组件;v-show只是简单的基于css的切换。
  • 编译条件:v-if是惰性的,如果初始条件为假,则什么也不做,只有在条件第一次为真的时候才编译;v-show是在任何条件下,无论真假都被编译,任何被缓存,而且DOM元素保留。
  • v-if有更高的切换消耗;v-show有更高的初始渲染消耗。
  • v-if适合运营条件不大可能改变;v-show适合频繁的切换。

data为什么是一个函数而不是对象?

JS中的对象是引用类型的数据,当多个实例引用同一个对象时,只要一个实例对这个对象进行操作,其他实例中的数据也会发生变化。
而在vue中,更多的是想要复用组件,那就需要每个组件都有自己的数据,这样组件之间才不会互相干扰。
所以组件的数据不能写成对象的形式,而是要写成函数的形式。数据以函数返回值的形式定义,这样当每次复用组件的时候,就会返回一个新的data,每个组价都会有自己的私有数据空间,各自维护自己的数据,不会干扰其他组件的正常运行。

vue-router的懒加载如何实现

非懒加载:

import List from '@/components/list.vue'
const router = new vueRouter({
	routes:[{
		path:'/list',
		component:List
	}]
})

1)方法一:使用箭头函数+import动态加载

const List =() => import('@/components/list.vue')
const router = new vueRouter({
	routes:[{
		path:'/list',
		component:List
	}]
})

2)方法二:使用箭头函数+require动态加载

const router = new vueRouter({
	routes:[{
		path:'/list',
		component:resolve => import(['@/components/list]',resolve)
	}]
})

3)方法三:使用webpack的require.ensure技术,也可以实现按需加载。多个路由指定相同的chunkName,会合并打包成一个js文件。

// r就是resolve
const List = r => require.ensure([],()=>
r(require('@/components/list')),'list');
// 路由也是正常的写法  这种是官方推荐的写的 按模块划分懒加载 
const router = new Router({
  routes: [
  {
    path: '/list',
    component: List,
    name: 'list'
  }
 ]
})
)
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-07 13:45:45  更:2021-10-07 13:46:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 23:54:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码