JS

1/8/2019 js

# 原型原型链

原型是什么? 在 JavaScript 中原型是一个 prototype 对象,用于表示类型之间的关系。

原型链是什么?

​JavaScript 万物都是对象,对象和对象之间也有关系,并不是孤立存在的。 对象之间的继承关系,在 JavaScript 中是通过 prototype 对象指向父类对象, 直到指向 Object 对象为止,这样就形成了一个原型指向的链条,专业术语称之为原型链。

prototype 是构造器的一个属性。在 JS 中,每一个对象的构造器都有一个 prototype 属性。 prototype 在 JS 中用于原型继承,可以使构造器构造出来的多个对象可以共享原型的对象。 其实无论使我们自己自定义的构造器还是原生的构造器都有 prototype 属性。 JS 中的对象关系是通过原型继承来实现的,而且通常原型继承有很多的层级,这些不同的层级就构成了原型链。

# 更改元素样式

​ 定义好不同的样式

vue:通过变量动态控制 class

jq:通过$().addClass()/$().removeClass()

# JavaScript 中如何检测一个变量是一个 String 类型?请写出函数实现

typeof obj === 'string'
typeof obj === 'string'
obj.constructor === String

# 比较 typeof 与 instanceof

相同点:JavaScript 中 typeof 和 instanceof 常用来判断一个变量是否为空,或者是什么类型的。

typeof 的定义和用法:返回值是一个字符串,用来说明变量的数据类型。

细节:

(1)、typeof 一般只能返回如下几个结果:number,boolean,string,function,object,undefined。

(2)、typeof 来获取一个变量是否存在,如 if(typeof a!="undefined"){alert("ok")},而不要去使用 if(a) 因为如果 a 不存在(未声明)则会出错。

(3)、对于 Array,Null 等特殊对象使用 typeof 一律返回 object,这正是 typeof 的局限性。

Instanceof 定义和用法:instanceof 用于判断一个变量是否属于某个对象的实例。

# 请用 js 去除字符串空格?

str = str.replace(/\s*/g,"");//去除所有空格
str = str.replace(/^\s*|\s*$/g,"");//去除两头空格
str = str.replace( /^\s*/, “”);//去除左空格
str = str.replace(/(\s*$)/g, "");//去除右空格
str.trim()//局限性:无法去除中间的空格
str.trimLeft(),str.trimRight()//分别用于去除字符串左右空格。

# 怎样添加、移除、移动、复制、创建和查找节点?

1)创建新节点

createDocumentFragment() //创建一个 DOM 片段

createElement() //创建一个具体的元素

createTextNode() //创建一个文本节点

2)添加、移除、替换、插入

appendChild() //添加

removeChild() //移除

replaceChild() //替换

insertBefore() //插入

3)查找

getElementsByTagName() //通过标签名称

getElementsByName() //通过元素的 Name 属性的值

getElementById() //通过元素 Id,唯一性

# 如何理解闭包

1、定义和用法:当一个函数的返回值是另外一个函数,而返回的那个函数如果调用了其父函数内部的其它变量,如果返回的这个函数在外部被执行,就产生了闭包。

2、表现形式:使函数外部能够调用函数内部定义的变量。

3、实例如下:

(1)、根据作用域链的规则,底层作用域没有声明的变量,会向上一级找,找到就返回,没找到就一直找,直到 window 的变量,没有就返回 undefined。这里明显 count 是函数内部的 flag2 的那个 count 。

var count = 10 //全局作用域 标记为flag1
function add() {
  var count = 0 //函数全局作用域 标记为flag2
  return function() {
    count += 1 //函数的内部作用域
    alert(count)
  }
}
var s = add()
s() //输出1
s() //输出2

4、变量的作用域

要理解闭包,首先必须理解 Javascript 特殊的变量作用域。

变量的作用域分类:全局变量和局部变量。

特点:

1)、函数内部可以读取函数外部的全局变量;在函数外部无法读取函数内的局部变量。

2)、函数内部声明变量的时候,一定要使用 var 命令。如果不用的话,你实际上声明了一个全局变量!

5、使用闭包的注意点

1)滥用闭包,会造成内存泄漏:由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在 IE 中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

2)会改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

# 什么是跨域?跨域请求资源的方法有哪些?

1、什么是跨域?

由于浏览器同源策略,凡是发送请求 url 的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。存在跨域的情况:

网络协议不同,如 http 协议访问 https 协议。

端口不同,如 80 端口访问 8080 端口。

域名不同,如 qianduanblog.com 访问 baidu.com。

子域名不同,如 abc.qianduanblog.com 访问 def.qianduanblog.com。

域名和域名对应 ip,如 www.a.com 访问 20.205.28.90.

2、跨域请求资源的方法:

(1)、porxy 代理

定义和用法:proxy 代理用于将请求发送给后台服务器,通过服务器来发送请求,然后将请求的结果传递给前端。

实现方法:通过 nginx 代理;

注意点:1、如果你代理的是 https 协议的请求,那么你的 proxy 首先需要信任该证书(尤其是自定义证书)或者忽略证书检查,否则你的请求无法成功。

(2)、CORS 【Cross-Origin Resource Sharing】

定义和用法:是现代浏览器支持跨域资源请求的一种最常用的方式。

使用方法:一般需要后端人员在处理请求数据的时候,添加允许跨域的相关操作。如下:

res.writeHead(200, {
  'Content-Type': 'text/html; charset=UTF-8',
  'Access-Control-Allow-Origin': 'http://localhost',
  'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
  'Access-Control-Allow-Headers': 'X-Requested-With, Content-Type',
})

(3)、jsonp

定义和用法:通过动态插入一个 script 标签。浏览器对 script 的资源引用没有同源限制,同时资源加载到页面后会立即执行(没有阻塞的情况下)。

特点:通过情况下,通过动态创建 script 来读取他域的动态资源,获取的数据一般为 json 格式。

实例如下:

<script>
  function testjsonp(data) {
    console.log(data.name); // 获取返回的结果
  }
</script>
<script>
  var _script = document.createElement('script');
  _script.type = "text/javascript";
  _script.src = "http://localhost:8888/jsonp?callback=testjsonp";
  document.head.appendChild(_script);
</script>

缺点:

1、这种方式无法发送 post 请求(这里)

2、另外要确定 jsonp 的请求是否失败并不容易,大多数框架的实现都是结合超时时间来判定。

# jq 里面怎么改变元素的属性

​$().attr()

$().addClass()

$().removeClass()

# jq 选择器

​(1)、基本选择器:#id,class,element,*;

(2)、层次选择器:parent > child,prev + next ,prev ~ siblings

(3)、基本过滤器选择器::first,:last ,:not ,:even ,:odd ,:eq ,:gt ,:lt

(4)、内容过滤器选择器: :contains ,:empty ,:has ,:parent

(5)、可见性过滤器选择器::hidden ,:visible

(6)、属性过滤器选择器:[attribute] ,[attribute=value] ,[attribute!=value] ,[attribute^=value] ,[attribute$=value] ,[attribute*=value]

(7)、子元素过滤器选择器::nth-child ,:first-child ,:last-child ,:only-child

(8)、表单选择器: :input ,:text ,:password ,:radio ,:checkbox ,:submit 等;

(9)、表单过滤器选择器::enabled ,:disabled ,:checked ,:selected

# jq 按钮点击无反应

​ 首先确保用户确实点击了,在开发者工具里调试,看看是不是前端的错误

# $(this) 和 this 关键字在 jQuery 中有何不同?

$(this) 返回一个 jQuery 对象,你可以对它调用多个 jQuery 方法,比如用 text() 获取文本,用 val() 获取值等等。

而 this 代表当前元素,它是 JavaScript 关键词中的一个,表示上下文中的当前 DOM 元素。你不能对它调用 jQuery 方法,直到它被 $() 函数包裹,例如$(this)。

# $(document).ready()方法和 window.onload 有什么区别?

(1)、window.onload 方法是在网页中所有的元素(包括元素的所有关联文件)完全加载到浏览器后才执行的。

(2)、$(document).ready() 方法可以在 DOM 载入就绪时就对其进行操纵,并调用执行绑定的函数。

Last Updated: 5/8/2020, 9:59:16 AM