console.log(this.desc);
}
},
});
console.log(vm.name);
console.log(vm.sayName());
#### 二、Vue的构造函数
接收一个options参数
* 使用 instanceof 判断 this对象上是否出现了Vue的prototype,我们都知道this的指向是取决于谁调用
* this.\_init(options) 证明在这调用要么我们创建的实例上有\_init方法要么方法在Vue的prototype上,但是我们可以看到实例上并没有\_init方法 ,那么肯定在一个地方给Vue的prototype上加上了\_init方法 继续往下看
function Vue(options) {
if (!(this instanceof Vue)
) {
warn(‘Vue是一个构造函数,应使用“new”关键字调用’);
}
this._init(options);
}
//Vue() //错误的调用方式 进入警告判断 此时this指向window 然后window的 window.__proto__的指向的Window构造函数的prototype
#### 三 初始化initMixin(Vue)
在源码中会看到很多初始化的函数在这我们initMixin()
这个函数就是在Vue的原型上增加了\_init方法,方法接收一个参数,然后定义了vm变量,在我看的时候就想看看这个函数的this指向谁,其实也不难函数挂在Vue构造函数的原型上,调用还是在构造函数里面使用this调用,构造函数的this指向Vue实例,根据this的指向规则 此时的vm就指向了Vue构造函数的实例。
使用this的访问规则如果实例上没有就去原型上找
然后执行 initState(vm)
initMixin(Vue)
function initMixin(Vue) {
//prototype上增加init方法
Vue.prototype._init = function (options) {
var vm = this; //Vue实例
vm.age = 30
//代码进行了删减
initState(vm);
}
}
//这里只是举例测试
const vm = new Vue({})
console.log(vm.age) //30
#### 四 initState(vm)
这里就是对我们传入的data 或者methods进行不同的处理
//initState方法代码进行了删减
function initState(vm) {
vm._watchers = [];
var opts = vm.$options; //这里是我们在创建实例的时候传的参数
//如果传了methods 则去调用
if (opts.methods) { initMethods(vm, opts.methods); }
if (opts.data) {
initData(vm);
} else {
observe(vm._data = {}, true /* asRootData */);
}
}
#### 五 initMethods(vm, opts.methods)
如果有methods则取调用initMethods方法
前面主要是判断 methods中的值是不是函数,key有没有跟props冲突等
最后一段代码就是在vm的实例上增加方法vm[key]=methods[key],在读的时候我有这样一个以为为什么还要用bind改变this指向呢不本来就是写在vm实例上的方法吗 只能使用vm调用 那么方法的this不就指向vm吗?
/*
vm:构造函数实例
methods:我们传的methods对象
*/
function initMethods(vm, methods) {
var props = vm.$options.props;
//循环methods对象
for (var key in methods) {
{
//判断是否是函数 不是的化则作出警告
if (typeof methods[key] !== ‘function’) {
warn(
"Method “” + key + “” has type “” + (typeof methods[key]) + “” in the component definition. " +
“Did you reference the function correctly?”,
vm
);
}
//判断 methods 中的每一项是不是和 props 冲突了,如果是,警告。
if (props && hasOwn(props, key)) {
warn(
(“Method “” + key + “” has already been defined as a prop.”),
vm
);
}
//判断 methods 中的每一项是不是已经在 new Vue实例 vm 上存在,而且是方法名是保留的 _ $ (在JS中一般指内部变量标识)开头,如果是警告。
if ((key in vm) && isReserved(key)) {
warn(
"Method “” + key + “” conflicts with an existing Vue instance method. " +
“Avoid defining component methods that start with _ or $.”
);
}
}
//给实例增加methods中的方法 这样其实我们就已经可以用vm访问 到methods中的方法了
vm[key] = typeof methods[key] !== ‘function’ ? noop : bind(methods[key], vm);
}
}
问了群里大佬之后原来这步操作时为了防止用户改变this指向,专门做了个例子
在这我有定义了对象a里面有个age属性和fn,fn我赋值vm实例上的sayHi,然后a.fn()调用很明显this的指向已经被改变了,使用bind之后则不会
const vm = new Vue({
methods: {
sayHi() {
console.log(this.age, ‘hello-this’)
}
}
});
let a = {
age: 15,
fn: vm.sayHi
}
console.log(a.fn(), ‘vm’) //打印15
#### 六 initData(vm)
data是如何做到的使用this可以直接访问的,其实原理都一样,
首先在vm实例上增加了\_data,里面存的我们传入的data参数
function initData(vm) {
var data = vm.KaTeX parse error: Undefined control sequence: \n at position 279: …turn an object:\̲n̲' + …options.props;
var methods = vm.$options.methods;
var i = keys.length;
while (i–) {
var key = keys[i];
//判断key值有没有跟methods中的key重名
{
if (methods && hasOwn(methods, key)) {
warn(
(“Method “” + key + “” has already been defined as a data property.”),
vm
);
}
}
//判断key值有没有跟props中的key重名
if (props && hasOwn(props, key)) {
学习笔记
主要内容包括html,css,html5,css3,JavaScript,正则表达式,函数,BOM,DOM,jQuery,AJAX,vue等等
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
HTML/CSS
**HTML:**HTML基本结构,标签属性,事件属性,文本标签,多媒体标签,列表 / 表格 / 表单标签,其他语义化标签,网页结构,模块划分
**CSS:**CSS代码语法,CSS 放置位置,CSS的继承,选择器的种类/优先级,背景样式,字体样式,文本属性,基本样式,样式重置,盒模型样式,浮动float,定位position,浏览器默认样式
HTML5 /CSS3
**HTML5:**HTML5 的优势,HTML5 废弃元素,HTML5 新增元素,HTML5 表单相关元素和属性
**CSS3:**CSS3 新增选择器,CSS3 新增属性,新增变形动画属性,3D变形属性,CSS3 的过渡属性,CSS3 的动画属性,CSS3 新增多列属性,CSS3新增单位,弹性盒模型
JavaScript
**JavaScript:**JavaScript基础,JavaScript数据类型,算术运算,强制转换,赋值运算,关系运算,逻辑运算,三元运算,分支循环,switch,while,do-while,for,break,continue,数组,数组方法,二维数组,字符串
画属性,CSS3 新增多列属性,CSS3新增单位,弹性盒模型
[外链图片转存中…(img-fU7SERGT-1714173442548)]
JavaScript
**JavaScript:**JavaScript基础,JavaScript数据类型,算术运算,强制转换,赋值运算,关系运算,逻辑运算,三元运算,分支循环,switch,while,do-while,for,break,continue,数组,数组方法,二维数组,字符串