14GET和POST两种基本请求方法的区别

最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数。
HTTP的底层是TCP/IP。所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。你要给GET加上request body,给POST带上url参数,技术上是完全行的通的。

每天3个面试题精研 - 前端 - 第4天

GET产生一个TCP数据包;POST产生两个TCP数据包。

  1. GET与POST都有自己的语义,不能随便混用。

  2. 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。

  3. 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

13说出几个http协议状态码

200:请求成功
201:请求成功并且服务器创建了新的资源
302:服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来响应以后的请求。
304:自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。
400:服务器不理解请求的语法。
404:请求的资源(网页等)不存在
405:方法不被允许
500: 内部服务器错误

12vue双向数据绑定的原理

实现数据绑定的做法有大致如下几种:

1发布者-订阅者模式(backbone.js)
2脏值检查(angular.js)
3数据劫持(vue.js) vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
Object.defineProperty(obj, prop, descriptor)

参数
obj 要在其上定义属性的对象。
prop 要定义或修改的属性的名称。
descriptor 将被定义或修改的属性描述符。

属性描述符

对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。存取描述符是由getter-setter函数对描述的属性。描述符必须是这两种形式之一;不能同时是两者。

数据描述符和存取描述符均具有以下可选键值(共同属性):

configurable
当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。

enumerable
当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为 false。

数据描述符同时具有以下可选键值:

value
该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。

writable
当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为 false。

存取描述符同时具有以下可选键值:

get
一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。
默认为 undefined。

set
一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。
默认为 undefined。

描述符可同时具有的键值

			configurable	enumerable	value	writable	get	set
数据描述符	Yes	Yes	Yes	Yes	No	No
存取描述符	Yes	Yes	No	No	Yes	Yes

如果一个描述符不具有value,writable,get 和 set 任意一个关键字,那么它将被认为是一个数据描述符。如果一个描述符同时有(value或writable)和(get或set)关键字,将会产生一个异常。

记住,这些选项不一定是自身属性,如果是继承来的也要考虑。为了确认保留这些默认值,你可能要在这之前冻结 Object.prototype,明确指定所有的选项,或者通过 Object.create(null)将__proto__属性指向null。

经典案例:

		<script type="text/javascript">
			var data = {name: 'kindeng'};
			observe(data);
			data.name = 'dmq'; // 哈哈哈,监听到值变化了 kindeng --> dmq

			function observe(data) {
				if (!data || typeof data !== 'object') {
					return;
				}
				// 取出所有属性遍历
				console.log(Object.keys(data));  //["name"]
				
				Object.keys(data).forEach(function(key) {
					console.log(key);   //name
					defineReactive(data, key, data[key]);  //{name: 'kindeng'},name,kindeng
				});
			};

			function defineReactive(data, key, val) {
				observe(val); // 监听子属性
				Object.defineProperty(data, key, {
					enumerable: true, // 可枚举
					configurable: false, // 不能再define
					get: function() {
						return val;
					},
					set: function(newVal) {
						console.log('哈哈哈,监听到值变化了 ', val, ' --> ', newVal);
						val = newVal;
					}
				});
			}
		</script>

例子中函数拓展
1Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for…in 循环遍历该对象时返回的顺序一致 。

Object.keys(obj)
参数
obj 要返回其枚举自身属性的对象。

返回值 一个表示给定对象的所有可枚举属性的字符串数组。

Object.create(proto, [propertiesObject])
Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。 (请打开浏览器控制台以查看运行结果。)

参数
proto 新创建对象的原型对象。
propertiesObject 可选。如果没有指定为 undefined,则是要添加到新创建对象的可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)对象的属性描述符以及相应的属性名称。这些属性对应Object.defineProperties()的第二个参数。

返回值
一个新对象,带着指定的原型对象和属性。

注:如果propertiesObject参数是 null 或非原始包装对象,则抛出一个 TypeError 异常。

经典案例:

		const person = {
			  isHuman: false,
			  printIntroduction: function () {
				console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);   //es6 新的语法$ {NAME},并把它放在反引号里
			  }
			};

			const me = Object.create(person);

			me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
			me.isHuman = true; // inherited properties can be overwritten

			me.printIntroduction();
			// expected output: "My name is Matthew. Am I human? true"

document.createDocumentFragment() 创建一个文档碎片
说白了就是为了节约使用DOM。每次JavaScript对DOM的操作都会改变页面的变现,并重新刷新整个页面,从而消耗了大量的时间。为解决这个问题,可以创建一个文档碎片,把所有的新节点附加其上,然后把文档碎片的内容一次性添加到document中。

经典案例:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<ul id="ul">
		</ul>
		<script type="text/javascript">
			var element  = document.getElementById('ul'); // assuming ul exists
			var fragment = document.createDocumentFragment();
			var browsers = ['Firefox', 'Chrome', 'Opera', 
					'Safari', 'Internet Explorer'];

			browsers.forEach(function(browser) {
					var li = document.createElement('li');
					li.textContent = browser;
					fragment.appendChild(li);
			});

			element.appendChild(fragment);
		</script>
	</body>
</html>

仿vue双向绑定的简易demo(因为太大用链接下载)
https://github.com/DMQ/mvvm

相关文章:

  • 2022-01-01
  • 2021-07-28
  • 2021-09-22
  • 2021-04-25
  • 2021-07-30
  • 2021-09-09
  • 2021-07-12
猜你喜欢
  • 2022-12-23
  • 2021-09-19
  • 2021-05-05
  • 2022-12-23
  • 2021-06-27
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案